2014-12-11 2 views
0

я задал следующий вопрос if a variable is defined in a class extends a trait, how to use it in the trait?почему вал работать, но вар не в конструкторе в этом случае (Скале)

И один из ответа, как показано ниже:

trait T1 { def a: String; def x = a.length } 
class Test(val a: String) extends T1 

Но если работает только :

  1. определит в T1, как «Защита а», если я использую «Вэлы а» или «вар а», то он не работает
  2. определит в тесте, как «в l a ", если я просто использую" a ", что означает по умолчанию значение" var a ", оно также не работает.

Почему это происходит?

+2

«Это не работает» не описывает ошибку, которую вы видите. * Всегда * описывайте фактическую ошибку. –

+1

Работает для меня: 'scala> trait T1 {val a: String; Защиту х = a.length} определена черта T1 Scala> Класс Test (значение: с String) расширяет T1 определенный класс Test > новый Scala Test ("Foo") х res0:. Int = 3' – Dima

+1

Это Безразлично 't "по умолчанию' var a' "- если вы пишете' class Test (a: String) ', то это * not * совпадает с' class Test (var a: String) '. Для классов case это то же самое, что 'val a', но не' var a'. – Jesper

ответ

2

«# 1» должен работать, как я упоминал в комментарии. Что касается # 2, там две вещи:

  1. class Test(a: String) является не такой же, как class Test(var a: String) (во всяком случае, это на самом деле ближе к val декларации, но не то же самое либо, за исключением случая классов) , Последний объявляет a в качестве изменяемого члена класса, в то время как первый просто делает его аргументом для конструктора, а не является членом класса вообще. По этой причине в вашем случае это терпит неудачу: вы должны переопределить абстрактный элемент a от T1, чтобы иметь возможность его продлить.

  2. class Test(var a: String) также не будет работать. Это связано с тем, что a объявлен в T1 как def, что делает его неизменным. Вы можете переопределить def с помощью def или val, но вы не можете переопределить его с изменяемым значением. Если вам нужно изменить его на Test, вы должны объявить его var в T1.

+1

'class Test (a: String)' больше похож на 'class Test (private [this] val a: String)'. – Jesper

+0

@ Dima: вы сказали: «Это потому, что a объявлен в T1 как def, что делает его неизменным», почему def является неизменным? каждый раз, когда def run, он может возвращать другой объект. say: def x = new someObject() –

+0

Ну, на самом деле, похоже, что я был неправ. Оказывается, что, по крайней мере, в scala 2.9.3 вы * можете * переопределить 'def' с' var': 'trait Foo {def x: Int}; класс bar (var x) расширяет Foo; ' работает для меня ... Я могу поклясться, что это не сработало, но не знаю, когда изменилось поведение – Dima

Смежные вопросы