scala中的`type`和“`关键字的调查
有人可以解释类型关键字和#操作符在
scala中的工作原理以及如何使用它?
请看例子. //Example1 scala> type t1 = Option.type defined type alias t1 //Shouldn't this work since previous example simply works? scala> type t2 = String.type <console>:7: error: type mismatch; found : String.type required: AnyRef type t2 = String.type ^ //lets define custom trait T scala> trait T defined trait T //... and obtain it's type like in Example1. //Shouldn't this work since previous Example1 simply works? scala> type t3 = T.type <console>:7: error: not found: value T type t3 = T.type ^ //Lets define some value of type T scala> val v4 = new T{} v4: T = $anon$1@5c3e8c76 //and obtain it's type (works) scala> type t4 = v4.type defined type alias t4 //this doesn't work scala> type t4_1 = (new T{}).type <console>:1: error: identifier expected but 'new' found. type t4_1 = (new T{}).type //as well as this (doesn't work) scala> type t5 = "abc".type <console>:1: error: identifier expected but string literal found. type t5 = "abc".type ^ //but this compiles well scala> val v6 = "abc" v6: String = abc scala> type t6 = v6.type defined type alias t6 //lets create some values of created types: scala> type t1 = Option.type defined type alias t1 scala> val v1_1 = Some(10) v1_1: Some[Int] = Some(10) scala> type t7 = v1_1.type defined type alias t7 scala> val v7:t7 = null v7: t7 = null scala> val v7_1:t7 = v1_1 v7_1: t7 = Some(10) scala> val v7_2:t7 = Some(10) <console>:9: error: type mismatch; found : Some[Int] required: t7 (which expands to) v1_1.type val v7_2:t7 = Some(10) ^ //next let's try # operator scala> class X[A,B](a:A,b:B) defined class X //doesn't work scala> type xa = X[A,B]#A <console>:8: error: not found: type A type xa = X[A,B]#A ^ <console>:8: error: not found: type B type xa = X[A,B]#A ^ //but such approach works: scala> trait X2[C]{ type A type B val c:C } defined trait X2 scala> type xa2_1 = X2[String]#A defined type alias xa2_1 scala> type xa2_2[M] = X2[M]#A defined type alias xa2_2 解决方法
首先,您关于类型的问题:
类型声明的右侧必须是具有稳定路径的类型的名称.所以把你的例子一个接一个: type t1 = Option.type t1是Option对象的类型的别名,而不是Option类. type t2 = String.type 这是一个错误,因为没有String对象.该错误有点奇怪,因为String的Java类并且因此在不同的规则下运行(因为Java类从来没有随播广告). type t3 = T.type 同上.这一次,错误更清楚,因为T是Scala类,所以编译器可以明确地说“T不使用类型命名对象” type t4 = v4.type 这是由val v4命名的对象的单例类型.它不是指任何类型T的实例,甚至是新的T {}表达式创建的任何匿名类的实例.它指的是仅由v4和null表示的类型,即它们是该类型的唯一允许值. type t4_1 = (new T{}).type 这是非法的,因为您正在使用的类型必须是一个稳定的标识符(大致是一个标识符,其引用者永远不会改变) – 如果idenfier的完整路径仅包含包,对象和vals的名称,它是稳定的). type t5 = "abc".type 同上. type t6 = v6.type v6是一个稳定的标识符. t6是由名称为v6(和null)引用的String的特定实例单独居住的类型. type v6 = v1_1.type 再次,单身类型. val v7: t7 = null null是t7类型的有效值 val v7_1:t7 = v1_1 这是特定的对象. val v7_2:t7 = Some(10) 但是这是一个不同的对象(即使它是==到v7,它不等于它),因此不是这种类型的成员. 现在关于#: class X[A,b:B) A和B是类型参数.他们不能在课外参考.你可以将它们看作是具有私有的这种可见性的抽象类型别名,尽管这不是很准确. type xa = X[A,B]#A 那么是的,不可见. type xa2_1 = X2[String]#A 由于这个A指的是一个公共类型的别名,它可以通过类外面的名字引用.请注意,这种特殊情况是相当无用的,因为您对此类型绝对没有任何意见.如果你的特质X2有一个返回值类型A的方法,你可以做一些类似的事情 val aFromX2: xa2_1 = x2instance.methodThatReturnsAnA ..但是你不能做任何其他事情,甚至把它传回到一个X2 [String]的一个实例,因为不能保证两个As将指向相同的类型!另一方面,如果你有一个具体的实例,你可以这样做: def passAroundA(x2instance: X2[String]) { type x2a = x2instance.A // note dot,not # val a: x2a = x2instance.methodThatReturnsAnA x2instance.methodThatTakesAnA(a) } 在这种情况下,它的作用是因为即使我们不知道A实际是什么,我们知道这两种方法使用相同的类型 – 无论是在x2instance的构造中修复的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |