2012-01-01 2 views
8

Я хотел бы сделать что-то вроде этого (например, упрощена, но содержит все важные части):Puzzle - разоблачение публичного суб-члена частного члена с пользовательского типа

class Master 
{ 
    type DataType = Int 
    var counter : DataType = 0 
} 

class Slave(private val master : Master) 
{ 
    val counter = master.counter // (*) 
} 

И здесь (*) Я получаю сообщение об ошибке:

private value master escapes its defining scope as part of type Slave.this.master.DataType

val counter = master.counter

Я понимаю ошибку, но я не понимаю причины - тип является частью класса Master, а не объект master, поэтому очень важно, если класс является частным, а не объект. Ну, по крайней мере теоретически.

Это легко сделать быстрый обходной путь:

val counter : Master#DataType = master.counter 

Но я считаю, что это явная версия точно тот же код, как и раньше, это «только» занимает больше печатать. Это функция?

ВОПРОС:

Может типа (здесь DataType) зависит от объекта, а не класс (т.е. определение типа на экземпляр класса) в Scala?

ответ

14

Вы не правы, когда вы думаете

this is an explicit version of the exactly same code as before

Master#DataType и master.DataType два различных типов.

master.DataType является типом этих DataType экземпляров, которые имеют master как внешний объект. Другими словами, именно то, что вы просите, но, очевидно, тогда masterесть часть типа, и тип не может быть выставлен, если master нет.

Master#DataType является типом любого экземпляра DataType для любого внешнего объекта (что эквивалентно Master.DataType на Java).

Ответ на комментарии:

Члены типа могут быть переопределены в подклассе (в том числе анонимного подкласса, содержащий только один объект), но только с помощью совместимого типа. А в вашем примере DataType уже конкретный в Master, поэтому единственный совместимый класс с ним сам. Так что-то вроде

val a = new Master { 
    override type DataType = String 
} 

не typecheck, что имеет смысл: вы получите var counter: String = 0, что это нонсенс. Но

val a = new Master { 
    override type DataType = Int 
} 

будет работать (но не слишком полезен).

Таким образом, имеет смысл переопределить аннотация членов типа. Но они проверяются по типу так же, как и внутренние классы, поэтому a.DataType обычно не считается таким же, как b.DataType - даже если они не могут быть разными!

+0

Спасибо, поэтому, если я это правильно понял (однако я не читал его в «Программирование в Scala», я верю - или, может быть, он поскользнулся), вы можете определить тип для экземпляра класса не только для каждого класса , – greenoldman

+0

Благодарим за обновление, это очень ценно, к сожалению, я не могу продвигать ваше сообщение более 1 :-) – greenoldman

+0

Это одна из тех полезных вещей в Scala, которая может быть «полученной» при выходе с других языков ООП. Очень краткий ответ; стоит моего upvote;). – TechNeilogy

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