Scala 推断/铸造通用类型至混凝土类型

Scala 推断/铸造通用类型至混凝土类型,scala,type-erasure,Scala,Type Erasure,当我尝试编译时: package com object typeparam extends App { new MyClass[Int]().f2(3) class MyClass[B] { def f2(b: B): B = { b + b } } } 我收到编译器错误 type mismatch; [error] found : B [error] required: String [error] b + b [err

当我尝试编译时:

package com

object typeparam extends App {

  new MyClass[Int]().f2(3)

  class MyClass[B] {

    def f2(b: B): B = {
      b + b
    }

  }

}
我收到编译器错误

type mismatch;
[error]  found   : B
[error]  required: String
[error]       b + b
[error]           ^
[error] one error found
为什么b不被推断为Int,就像我调用类时使用类型参数Int一样

如果我改为使用:

package com

object typeparam extends App {

  println(new MyClass[Int]().f2(3) * 3)

  class MyClass[B] {

    def f2(b: B): B = {
      b
    }

  }

}
正确打印值9。因此,Int类型的推断似乎是正确的


这与类型擦除有关吗?

它与类型擦除无关。您的类型参数
B
是无界的,并且不是每个类型都有
+
方法。但是每种类型都可以隐式转换为
String
,以便使用
+
方法(推断为
Any
),这正是这里发生的事情

如果您希望此功能仅适用于数字,则可能需要
数字
特性

class MyClass[B](implicit num: Numeric[B]) {
   def f2(b: B): B = num.plus(b, b)
}

scala> def myInst = new MyClass[Int]
myInst: MyClass[Int]

scala> myInst.f2(3)
res0: Int = 6

谢谢,这种情况下数字没问题。因此,使用“implicit num:Numeric[B]”将“B”绑定为Int类型?它添加了一个约束:编译器不允许您实例化MyClass,除非B是数值类型(这实际上意味着有Numeric[B]的隐式实例可用)。