Можно ли в Scala создать экземпляр с переменной, относящейся к другому классу или признаку?

Я хочу создать экземпляр с переменной, обозначающей некоторую черту, как показано ниже, что дает вам ошибку. Есть ли способ сделать это в scala?

var traitRefer = classOf[SomeTrait]
var a = new SomeClass() with traitRefer

person Elonoa    schedule 14.03.2012    source источник
comment
В этом нет смысла. Этот код такой же, как и в java: Class<?> traitRefer = SomeTrait.class; class a extends SomeClass implements traitRefer traitRefer - это просто переменная !!!!   -  person Andrzej Jozwik    schedule 14.03.2012


Ответы (3)


Отличный вопрос! В вашем понимании вам не хватает того, что происходит во время компиляции по сравнению с тем, что происходит во время выполнения.

Когда компилятор Scala встречает такое выражение, как new Foo with Bar, во время компиляции он генерирует анонимный внутренний класс, который по сути совпадает с class Anonymous extends Foo with Bar. Затем компилятор делает все возможное, чтобы получить желаемый результат. Базовый класс и расширенные свойства должны быть определены во время компиляции; вы не можете определить их во время выполнения. *

Поскольку типаж, который вы хотите добавить, неизвестен до времени выполнения, компилятор не знает, что сгенерировать для анонимного класса.

Я предполагаю, что ваша черта использует преимущества стекируемых черт для изменения поведение SomeClass. В качестве альтернативы вы можете использовать шаблон декоратора и выбрать декоратор во время выполнения.

(*) Что вы можете сделать во время выполнения, так это сгенерировать байт-код для нового класса. Есть множество способов сделать это, включая встраивание компилятора Scala. Однако это не для ловкости сердца. Несомненно, есть более простой способ выполнить то, что вы пытаетесь сделать.

person leedm777    schedule 14.03.2012
comment
Да, я хотел динамически применить некоторые черты, и теперь я знаю, почему это невозможно. Шаблон дизайна может быть полезен. Спасибо всем - person Elonoa; 15.03.2012

Я не думаю, что есть другой способ сделать это, кроме отражения, потому что это небезопасно. Что вы могли бы сделать, так это создать экземпляр с определенным признаком, смешанным с сопоставлением с образцом. Например.

kind match {
  case "Foo" => new SomeClass with Foo
  case "Bar" => new SomeClass with Bar
}
person drexin    schedule 14.03.2012

Думаю, это невозможно (исключить рефлексию). См. Больше здесь. Ты можешь это сделать:

type Ref = SomeTrait
var a = new SomeClass with Ref

Но я думаю, это не то, что ты хочешь

person Sergey Passichenko    schedule 14.03.2012