kas*_*ens 12 type-systems jvm scala
我注意到,如果不可能设置多个下限(因此它可能是最低常见超类型的迭代器),tuple.productIterator总会返回一个Iterator[Any]想知道的问题.
我尝试了一下搜索,但只发现了这个问题的多个上界.
这是我对如何定义迭代器类型的测试:
def f[A,B](a:A, b:B) = List(a,b)
// return type is List[Any]
def f[A,B, T >: A "and" T >: B](a:A, b:B) = List[T](a,b)
// doesn't compile, but
// f(1, true) should give a List[AnyVal] and
// f("x", "y") a List[String]
Run Code Online (Sandbox Code Playgroud)
这是JVM的限制吗?
class Foo[A, B](a: A, b: B) {
def f[T >: A] = List[T](a) // works
def g[T >: A "and" T >: B] = List[T](a) // doesn't work
}
Run Code Online (Sandbox Code Playgroud)
Jea*_*let 10
对于简单的情况,其中A和B编译器同时绑定T,IttayD的答案工作正常:
def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
Run Code Online (Sandbox Code Playgroud)
当你的示例中已经绑定A并且B已经绑定时class Foo[A, B],需要引入临时虚拟变量以使编译器完成此任务:
class Foo[A, B](a: A, b: B) {
def g[T, A1 >: A <: T, B1 >: B <: T] = List[T](a: A1, b: B1)
}
Run Code Online (Sandbox Code Playgroud)
(为了清楚起见:A1 >: A <: T意味着类型A1必须的超类型A和子类型T,并不算A是两者的亚型A1和T).
A1并且B1这里的唯一目的是推断出正确的类型T.如果编译器来推断他们,他们会下定决心,A1 = A和B1 = B,然后T作为最具体类型,是两者的超A和B.
但是,编译器没有意识到的一件事是,通过传递性,我们有两个T >: A和T >: B,它直接来自关于A1和的约束B1.我们需要帮助解决类型问题.
现在,Product#productIterator不能使用这种技术,因为它在一个地方的定义,我们甚至不知道A和B,或确实有多少类型的参数中有具体子类.