scala – 存在类型和类型成员
什么工作(A部分)
假设我有一个类型参数的特征: trait A[T] 我可以使用一个存在类型来编写一个将收集的方法,因为它们都具有相同的T: def foo(as: Seq[A[X]] forSome { type X }) = true 请注意,这与以下不同: def otherFoo(as: Seq[A[X] forSome { type X }]) = true 或相当于: def otherFoo(as: Seq[A[_]]) = true 在这些情况下,存在的范围在Seq内,所以As可以有不同的Ts.有了我原来的foo(在Seq的存在范围上),以下是很好的: foo(Seq(new A[Int] {},new A[Int] {})) 但是使类型参数不同,它不会编译: scala> foo(Seq(new A[Int] {},new A[String] {})) <console>:10: error: type mismatch; found : Seq[A[_ >: java.lang.String with Int]] required: Seq[A[X]] forSome { type X } foo(Seq(new A[Int] {},new A[String] {})) ^ 这一切都很简单. 什么工作(B部分) 现在假设我有一个类型的成员,而不是一个类型参数: trait B { type T } 我可以写一个方法,只能使用一些指定的T: scala> def bar[X](b: B { type T = X }) = true bar: [X](b: B{type T = X})Boolean scala> bar[Int](new B { type T = Int }) res5: Boolean = true scala> bar[String](new B { type T = Int }) <console>:10: error: type mismatch; found : java.lang.Object with B required: B{type T = String} bar[String](new B { type T = Int }) ^ 再次,这是完全符合你期望的方式. 什么不行 当我们尝试写相当于我们上面的foo,但对于类型成员,事情变得奇怪. scala> def baz(bs: Seq[B { type T = X }] forSome { type X }) = true baz: (as: Seq[B{type T = X}] forSome { type X })Boolean scala> baz(Seq(new B { type T = Int },new B { type T = String })) res7: Boolean = true 最后一行编译对我来说没有意义.我已经告诉我,我想让所有的类型成员是一样的.我的foo显示我可以为类型参数执行此操作,而bar显示可以基于类型成员约束类型.但我不能结合这两个. 我在2.9.2和2.10.0-M5上试了一下. 动机 这个问题的灵感来自this one,在那里我的第一个想法是,哦,只是使用一种存在的类型(将这个可以在这里使用的it seems to be impossible to get an existential type to scope of the type of a repeated parameter的问题放在一边): def accept(rs: Seq[RList[Int] { type S = X }] forSome { type X }) = true 但是这并没有真正的工作 – 你得到与上面简化例子相同的奇怪的结果. 解决方法
我终于明白了(至少我希望如此).我们来做另一回事.我们建立我们的特质:
scala> trait B {type T} defined trait B 我们尝试建立一个B序列: scala> Seq(new B {type T = Int},new B {type T = String}) res0: Seq[B{type T >: String with Int}] = List($anon$1@592b12d,$anon$2@61ae0436) 死了,它的作品!好的,我们没有类型T的平等,但让我们玩它: scala> res0 : (Seq[B {type T = X}] forSome {type X >: String with Int}) res1: Seq[B{type T = X}] forSome { type X >: String with Int } = List($anon$1@592b12d,$anon$2@61ae0436) 更接近不要等等,这并不紧密,比你提出的baz参数要好,我们不仅提供了一个原始类型,还有一个上限!因此,我们可以明确地将其传递给巴兹.这就是为什么它不按预期工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |