Scala中的多个下限类型 [英] Multiple lower type bounds in Scala

查看:81
本文介绍了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
}

推荐答案

对于AB由编译器与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)

AB已经像您的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是两者的子类型A1T.)

(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.)

A1B1的唯一目的是为T推断正确的类型.如果编译器必须推断它们,它们将解析为A1 = AB1 = B,然后解析为T作为最具体的类型,它是AB的超类.

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 >: AT >: B,这直接源自对A1B1的约束.我们需要提供类型归因的帮助.

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无法使用此技术,因为它是在我们甚至都不知道AB或具体子类中确实有多少类型参数的地方定义的.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆