Reputation: 4419
I saw some code write trait as following:
trait SelfAware { self: Self =>
....
}
class Self
val s = new Self with SelfAware // this is ok
println(s.self) // error happened
class X
new X with SelfAware // error happened here
I'd like to know why the error happened and how to use trait in this way?
Upvotes: 29
Views: 18051
Reputation: 4419
I also found the answer here: http://markthomas.info/blog/?p=92
Ordered can be mixed in to any class; it doesn’t depend on any methods or fields of the class that it is mixed in to. Sometimes it’s useful for a trait to be able to use the fields or methods of a class it is mixed in to, this can be done by specifying a self type for the trait. A self type can be specified for a class or a trait as follows:
trait SpellChecker { self =>
...
}
self within the context of this trait will refer to this. Aliasing this is useful for nested classes or traits where it would otherwise be difficult to access a particular this. The syntax can be extended to specify a lower-bounds on this, when this is done the trait or class can use the features of this lower-bound class, so it can extend or modify its behaviour.
trait SpellChecker { self: RandomAccessSeq[char] =>
...
}
The compiler will check that any class in a hierarchy including SpellChecker is or extends RandomAccessSeq[char], so SpellChecker can now use the fields or methods of RandomAccessSeq[char]
Upvotes: 21
Reputation: 53675
To answer the other half of your question (why does println(s.self)
produce an error?), that is because self
is not a field of SelfAware
. It can be used to define such fields, however:
trait SelfAware { self =>
val me = self
}
class X
val x = new X with SelfAware
println(s.me)
Upvotes: 12
Reputation: 35054
The error is occurring because you have constrained the type of the this
reference (which you have named self
) to be of type Self
. When you say new Self with SelfAware
, this is OK, because that object is of type Self
like you asked. But when you say new X with SelfAware
, there is no evidence that X
is in any way a subtype of Self
.
In your new object of type X with SelfAware
, what would be the type of its self
member? Well, it would not be of type Self
, but of type X
. But you have defined the trait SelfAware
so that self
must be of type Self
, so you get a type error.
Upvotes: 22