简体   繁体   中英

Self in trait invisible from outside the trait?

trait A { def someMethod = 1}
trait B { self : A => }

val refOfTypeB : B = new B with A

refOfTypeB.someMethod

The last line results in a type mismatch error. My question is: why it's impossible to reach the method (of A) when it's given that B is also of type A?

So B is not also of type A . The self type annotation that you've used here indicates specifically that B does not extend A but that instead, wherever B is mixed in, A must be mixed in at some point as well. Since you downcast refOfTypeB to a B instead of B with A you don't get access to any of type A 's methods. Inside of the implementation of the B trait you can access A 's methods since the compiler knows that you'll at some point have access to A in any implemented class. It might be easier to think about it as B depends on A instead of B is an A .

For a more thorough explanation see this answer: What is the difference between self-types and trait subclasses?

The problem is when you declare refOfTypeB, you have type B specified but not type B with A.

The self => syntax allow you to access the properties of A within B and pass the compilation.

However, in the runtime, refOfTypeB is not recognize as B with A and the compiler doesn't necessarily have the function map correctly.

So, the correct syntax should be:

trait A { def someMethod = 1}
trait B { self : A => }

val refOfTypeB : B with A = new B with A

refOfTypeB.someMethod //1

Indeed, this is more expressive in terms of explaining with what refOfTypeB exactly is.

This is the somehow the boilerplate of cake patterns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM