Scala中的多个下限类型 [英] Multiple lower type bounds in Scala
问题描述
我注意到tuple.productIterator
总是返回一个Iterator[Any]
,想知道是否无法设置多个下限(因此它可能是最低普通超类型的Iterator).
I noticed that tuple.productIterator
always returns an Iterator[Any]
an wondered if it's not possible to set multiple lower bounds (so it could be an Iterator of the lowest common super type).
我尝试并搜索了一下,但只发现了此有关多个上限的问题.
I tried and searched a bit, but only found this question for multiple upper bounds.
这是我关于如何定义迭代器类型的测试:
This is my test on how to define the the type of the iterator:
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的限制吗?
这是一个更大的示例,当应该在方法中定义T时,使用IttayD方法似乎无法解决:
Here's a slightly bigger example which doesn't seem to be solvable using IttayD approach when T should be defined in the method:
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的答案效果很好:
For the simple case where A
and B
are bound by the compiler as the same time as T
, IttayD's answer works fine:
def f[T, A <: T,B <: T](a:A, b:B) = List[T](a,b)
当A
和B
已经像您的class Foo[A, B]
示例中那样被绑定时,您需要引入临时哑变量以使编译器完成此工作:
When A
and B
are already bound as in your class Foo[A, B]
example, you need to introduce temporary dummy variables to have the compiler do this job:
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
.)
(For the sake of clarity: A1 >: A <: T
means that type A1
must be a supertype of A
and a subtype of T
, and not that A
is a subtype of both A1
and T
.)
A1
和B1
的唯一目的是为T
推断正确的类型.如果编译器必须推断它们,它们将解析为A1 = A
和B1 = B
,然后解析为T
作为最具体的类型,它是A
和B
的超类.
A1
and B1
are here for the sole purpose of inferring a correct type for T
. If the compiler has to infer them, they will resolve to A1 = A
and B1 = B
, and then T
as the most specific type which is a superclass of both A
and B
.
尽管如此,编译器没有意识到的一件事是,由于传递性,我们同时具有T >: A
和T >: B
,这直接源自对A1
和B1
的约束.我们需要提供类型归因的帮助.
One thing that the compiler doesn't realize, though, is that, by transitivity, we have both T >: A
and T >: B
, which follows directly from the constraints with respect to A1
and B1
. We need to help out with the type ascriptions.
现在,Product#productIterator
无法使用此技术,因为它是在我们甚至都不知道A
和B
或具体子类中确实有多少类型参数的地方定义的.
Now, Product#productIterator
could not use this technique, as it's defined in a place where we don't even know A
and B
, or indeed how many type parameters there are in the concrete subclass.
这篇关于Scala中的多个下限类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!