mixin: методът е споменат в дефиницията, но не е в нито един от интерфейсите

Прочетох ръководството за ракети 13.7.3 Параметризирани миксини

Използвам параметризирани миксини, за да създам клас good-eat-fish% от fish%

(define fish-interface
  (interface () eat get-size))

(define fish%
  (class* object% (fish-interface)
    (init size)
    (super-new)
    (define current-size size)
    (define/public (get-size) current-size)
    (define/public (eat other)
      (set! current-size (+ current-size (send other get-size))))))

(define (good-eat-mixin member-name)
  (define eat member-name)
  (mixin () ()
    (inherit eat)
    (define/public (good-eat y)
      (eat y) (eat y))))

(define good-eat-fish%
  ((good-eat-mixin (member-name-key eat)) fish%))

Когато стартирам кода, се появява следната грешка:

"mixin: method was referenced in definition, but is not in any of the from-interfaces
  method name: eat
  from-interfaces:"

Това съобщение за грешка показва ли, че няма метод eat?

Ако променя кода на

(define (good-eat-mixin member-name)
  (define eat member-name)
  (mixin (interface () eat) (interface () eat good-eat)
    (inherit eat)
    (define/public (good-eat y)
      (eat y) (eat y))))

Получавам тази грешка:

interface: bad syntax in: interface

За съжаление, не знам защо

interface () eat) 

е лош синтаксис.


person Xi Jh    schedule 14.04.2013    source източник


Отговори (1)


За първия проблем: миксините налагат няколко проверки за злоупотреба и вие се натъквате на тях. Например, ако просто направите:

(mixin () ()
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

тогава системата открива, че кодът се опитва да зависи от eat метод, който не е част от декларирания интерфейс на mixin. Вторият ви опит е по-близо, но имате нужда от допълнителни скоби. например от

(mixin (interface () eat) (interface () eat good-eat)
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

to:

(mixin ((interface () eat)) ((interface () eat good-eat))
  (inherit eat)
  (define/public (good-eat y)
    (eat y) (eat y)))

Дайте имена на интерфейсите, така че да се вижда по-лесно:

(define eater<%> (interface () eat))
(define good-eater<%> (interface () good-eat))
...
(mixin (eater<%>) (good-eater<%>)
  ...)

Ето един пример:

#lang racket

(define eater<%> (interface () eat))
(define good-eater<%> (interface () good-eat))

(define fish%
  (class* object% (eater<%>)
    (init size)
    (super-new)
    (define current-size size)
    (define/public (get-size) current-size)
    (define/public (eat other)
      (set! current-size (+ current-size (send other get-size))))))

(define fish-interface
  (interface () eat get-size))

(define good-eat-mixin
  (mixin (eater<%>) (good-eater<%>)
    (inherit eat)
    (super-new)
    (define/public (good-eat y)
      (eat y) (eat y))))

(define good-eat-fish%
  (good-eat-mixin fish%))

(define f1 (new good-eat-fish% [size 42]))
(define f2 (new good-eat-fish% [size 16]))
(send f1 eat f2)
(send f1 good-eat f2)
(send f1 get-size)

(Премахнах нещата с членския ключ от вашия пример, само за да опростя.)

Вярвам, че класовата система в racket/class е номинална, а не структурна.

person dyoo    schedule 16.04.2013
comment
Благодаря ти. Разбрах. С ваша помощ коригирам извадката на параметризираните миксини. - person Xi Jh; 19.04.2013