Это невозможно. Конечно, есть способы создания новых классов во время выполнения: просто используйте любой байт-код манипуляция библиотека . Но this.type
является не"классом this
", а единственным типом this
(и нет способа выразить "класс this
" в сигнатуре типа Scala )! Итак
def eat: this.type with Eaten = {
// may do something here, but in the end you have to return
this
}
И, конечно, если Apple
не расширяет Eaten
, он не скомпилируется, что бы вы ни делали внутри метода. Обычный обходной путь - что-то вроде
class Fruit[F : Manifest <: Fruit[F]] {
def eat: F with Eaten = {
val clazz = manifest[F].erasure
val result = // do your bytecode manipulations here
result.asInstanceOf[F with Eaten]
}
}
но это не сработает, если у вас более одного интерфейса маркера:
val apple = new Apple // Apple
val washed = apple.wash // Apple with Washed
val eaten = washed.eat // Apple with Eaten, but no longer Washed!