What is actuall class for structural type scala syntax definition?
Example:
type T = MyClass {def someMethod:String}
Does it mean for compiler creation of trait like "trait AnonTrait extends MyClass {def someMethod:String}
"? Or it is done via other compiler mechanism?
My question was wh开发者_运维技巧at is actually hidden by this Type syntax.
It doesn't hide the creation of a type. Basically it masks use of reflection to check your structural constraints at compile time and to invoke someMethod at runtime.
For instance, if you have:
class Foo(t: MyClass {def someMethod:String}) {
def CallSomeMethod = t.someMethod
}
this means the constructor for your Foo class accepts a t of type MyClass that also has a someMethod (where the someMethod could be mixed into MyClass via a trait). You could have:
class MyClass {}
trait WithSomeMethod {def someMethod = "hello"}
and you could then create Foo like this:
val mc = new MyClass with WithSomeMethod
val foo = new Foo(mc)
println(foo.CallSomeMethod) // prints "hello"
now, when you create new Foo(mc)
the compiler uses reflection to check that mc is a MyClass that also has a someMethod. The actual call foo.CallSomeMethod
works via reflection as well.
Now (bear with me, I'm getting to your actual question...) doing as you did:
type T = MyClass {def someMethod:String}
is only creating a type alias, not a concrete type. Once you have T defined that way, you can define Foo as:
class Foo(t: T) {
def CallSomeMethod = t.someMethod
}
this is equivalent to the definition of Foo given previously. You've just created an alias T that can be reused in other places where you might have used MyClass {def someMethod:String}
. No actual T type is generated and the compiler still uses reflection whenever you refer to T, to check the structural constraint that it does have a someMethod defined, and still generates code based on reflection to invoke someMethod.
It does not create a Trait, it only a type alias which means that each time your refer to T
, you refer in fact to MyClass {def someMethod:String}
. However, you can override type declaration with a trait:
trait A
class B {
type T <: A
}
class SubB {
trait T extends A
}
Consider this: a class does not have an structural type. The type of a class is always a class. A trait produces an interface. A singleton object's type is a class as well.
And where do structural types appear? As types to parameters and variables.
For example, I can say def f(s: { def size: Int })
, or val r: { def close(): Unit }
.
Now, how do these types appear as bytecode? Like any other type not supported by JVM (such as Java's own generics), they are erased.
So, as far as everyone else (ie, not Scala) is concerned, the types of s
and r
above are java.lang.Object
.
For Scala itself, some additional information is stored in an annotation, that gives the exact information about these types as Scala understands them.
精彩评论