什么是结构类型scala语法定义的实际类?

时间:2011-08-31 06:39:06

标签: scala

示例:

type T = MyClass {def someMethod:String} 

编译器创建像“trait AnonTrait extends MyClass {def someMethod:String}”这样的特征是否意味着什么?或者它是通过其他编译器机制完成的? 我的问题是这种Type语法实际上隐藏了什么。

3 个答案:

答案 0 :(得分:3)

它不会创建特征,它只是一个类型别名,这意味着每次您引用T时,您实际上都会引用MyClass {def someMethod:String}。但是,您可以使用特征覆盖类型声明:

trait A

class B {
  type T <: A
}

class SubB {
  trait T extends A
}

答案 1 :(得分:3)

它不会隐藏类型的创建。基本上它掩盖了使用反射来在编译时检查结构约束并在运行时调用someMethod。

例如,如果你有:

class Foo(t: MyClass {def someMethod:String}) {
    def CallSomeMethod = t.someMethod
}

这意味着你的Foo类的构造函数接受一个类型为MyClass的t,它也有一个someMethod(someMethod可以通过trait混入MyClass)。 你可以:

class MyClass {}
trait WithSomeMethod {def someMethod = "hello"}  
然后你可以像这样创建Foo:

val mc = new MyClass with WithSomeMethod
val foo = new Foo(mc)
println(foo.CallSomeMethod) // prints "hello"

现在,当您创建new Foo(mc)时,编译器使用反射来检查mc是否也是具有someMethod的MyClass。实际调用foo.CallSomeMethod也可以通过反射工作。

现在(忍受我,我正在回答你的实际问题......)正如你所做的那样:

type T = MyClass {def someMethod:String} 

仅创建类型别名,而不是具体类型。一旦你用这种方式定义T,就可以将Foo定义为:

class Foo(t: T) {
    def CallSomeMethod = t.someMethod
}

这相当于之前给出的Foo的定义。您刚刚创建了一个别名T,可以在您可能使用过MyClass {def someMethod:String}的其他地方重复使用。生成没有实际的T类型,并且编译器在引用T时仍然使用反射,以检查它确实具有someMethod定义的结构约束,并且仍然基于反射生成代码以调用someMethod。

答案 2 :(得分:3)

考虑一下:一个类没有结构类型。类的类型总是一个类。特征产生一个界面。单例对象的类型也是一个类。

结构类型出现在哪里? 作为参数和变量的类型。

例如,我可以说def f(s: { def size: Int })val r: { def close(): Unit }

现在,这些类型如何显示为字节码?与JVM不支持的任何其他类型(例如Java自己的泛型)一样,它们被擦除

因此,就其他所有人(即Scala而言)而言,上面sr的类型为java.lang.Object

对于Scala本身,一些附加信息存储在注释中,当Scala理解它们时,它会提供有关这些类型的确切信息。