子类型导致 Any: Bug in compiler 或 issue with my code?

Subtyping leads to Any: Bug in compiler or issue with my code?

让我直接进入我在处理类型边界时遇到的问题。
让我们考虑以下... 我创建了一个这样的函数 'foo'

def foo[A,B](x:A,y:B):(A,B)=(x,y)

我在 scala 工作表中调用了 foo,比如

foo("Mars",2400)

我得到了这样的结果

res0: (String, Int) = (Mars,2400)

注意火星和2400的推断类型
现在我想强制函数 'foo' 接受整数或浮点数或双精度数(任何类型是 AnyVal 的子类型)。

为了强制执行,我写了一个代码

def fooNew[A<:B,B](x:A,y:B):(A,B)=(x,y)

之前代码的推断类型是 (String,Int) 并且当我调用 fooNew 时

fooNew("Saturn",2400)

我很惊讶地看到编译器确实让我的代码通过了并且没有引发错误而是给出了类似

的输出
res0: (String, Any) = (Saturn,2400)

现在,所需的强制执行方式在这里不起作用。如果我做了这样的事情

def fooNew[A<:B,B<:AnyVal](x:A,y:B):(A,B)=(x,y)

编译器肯定会为我报错,它确实报错了!

Error:(2, 2) inferred type arguments [String,Any] do not conform to method fooNew's type parameter bounds [A <: B,B <: AnyVal]
fooNew("Saturn",2400);}

我想问一下,为什么编译器不将类型设置为Int,而是推断类型为Any,让我的代码通过类型检查?
我是否总是需要将第二种类型强制为 AnyVal 的子类型,而不是让编译器为我推断它?或者它是编译器中的错误。
如果您发现我的问题误导或不符合您的期望,请原谅。
目前我正在使用 scala-library 2.11.8
谢谢

def fooNew[A<:B,B](x:A,y:B):(A,B)=(x,y)

在上面,您将类型参数 A 声明为类型参数 B 的子类型。当您将 A 作为 String 传递,将 B 作为 Int 传递时,编译器会向上 class 层次结构查找合适的类型对于 B 这样 Int 是 B 并且 String 是 B 的子类型。满足这两个条件的层次结构中唯一的类型是 Any 类型。因此,String 是 Any 的子类型,而 Int 是 Any

类型

您可以考虑将您的原始声明与推断类型一起使用 "find A and B such that x has type A, y has type B, and A is a subtype of B"。由于 A = StringB = Any 满足这些条件,编译器正确地推断出它们(还有其他解决方案,例如 A = B = Any,但这个是最具体的)。

但是你可以改变声明来告诉编译器"find A and B such that x has type A and y has type B, and then check that A is a subtype of B"。这是按如下方式完成的:

def fooNew[A,B](x:A,y:B)(implicit evidence: A <:< B): (A,B)=(x,y)

这是可行的,因为编译器将只使用第一个参数列表来推断 AB。搜索 "generalized type constraints" 以查找有关 <:<=:=.

的更多信息