/ / Як можна змішати знаючі параметри типу загального суперкласу - scala, generics, mixins

Як змішувати можна знати типові параметри генеральні суперкласи - scala, generics, mixins

Давайте припустимо, що у мене є такий родовий тип, як цей:

class GenericEchoer[T <: Any] {
var content: T = _
def echo: String = "Echo: " + content.toString
}

Тоді можна створити міксин, який дозволив би розширити функціональність GenericEchoer [T] таким чином:

trait Substitution[T <: AnyRef] extends GenericEchoer[T] {
def substitute(newValue: T) = { content = newValue }
}

Визначивши ці дані, я можу створити тип таким чином:

val echoer = new GenericEchoer[Int] with Substitution[Int]

Моє запитання: як реалізувати подібну функціональність, щоб я міг опустити параметри типу в mixin? Іншими словами, мені б хотілося створювати один і той же тип за допомогою наступного рядка:

val echoer = new GenericEchoer[Int] with Substitution

Це, однак, не працює, оскільки Заміна "не знає" основний параметр типу.

Відповіді:

2 для відповіді № 1

Ви невірно вказуєте код, він навіть не компілюється.

Твій GenericEchoer не може бути class, викликай своє content member є абстрактним, або вам слід надати це за замовчуванням:

class GenericEchoer[T <: AnyRef] {
var content: T = _
def echo: String = "Echo: " + T.toString
}

Ви не можете писати T.toString, я думаю, ти хотів content.toString. Ви не можете пройти Int йому, викликати Int мав AnyVal як його супертип і ваша верхня межа T є AnyRef.

self.content в Substitution Також є незаконним, вам слід:

1) зробити self як селфітип:

trait Substitution[T <: AnyRef] extends GenericEchoer[T] { self =>
def substitute(newValue: T) = { self.content = newValue }
}

2) Замініть його на this 3) Просто піди { content = newValue }

Що стосується вашої проблеми. Ні, це неможливо. Я можу запропонувати вам замінити class з trait і введіть конструктор з абстрактним типом члена:

trait GenericEchoer {
type T <: AnyRef
var content: T = _
def echo: String = "Echo: " + content.toString
}

trait Substitution extends GenericEchoer {
def substitute(newValue: T) { content = newValue }
}

val enchoer = new GenericEchoer with Substitution { type T = String }

або краще

val enchoer = new GenericEchoer with Substitution {
type T = String
var content = "Hello" // either case it will be null
}