我注意到tuple.productIterator
总是返回一个Iterator[Any]
,想知道是否不可能设置多个下限(因此它可能是最低常见超类型的迭代器)。
我尝试并搜索了一下,但只找到this问题的多个上限。
这是我对如何定义迭代器类型的测试:
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]
这是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
}
对于A
和B
与T
同时被编译器绑定的简单情况,IttayD's answer工作正常:
def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
当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)
}
(为了清楚起见: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
的地方定义,或者实际上在具体子类中有多少类型参数。
听起来你需要的是一个HList:http://apocalisp.wordpress.com/2010/07/06/type-level-programming-in-scala-part-6a-heterogeneous-list%C2%A0basics/
回答具体问题:
scala> def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
f: [T, A <: T, B <: T](a: A, b: B)List[T]
scala> f(1, true)
res0: List[AnyVal] = List(1, true)
scala> f("x", "y")
res1: List[java.lang.String] = List(x, y)