首页 > 解决方案 > Scala 类型推断和隐式转换

问题描述

以下代码有效:

scala> import scala.language.implicitConversions
import scala.language.implicitConversions

scala> implicit val longToInt = (l: Long) => l.toInt
longToInt: Long => Int = $$Lambda$1821/0x000000010086e840@52bd9a27

scala> def printInt(n: Int) = println(n)
printInt: (n: Int)Unit

scala> val opt: Option[Long] = None
opt: Option[Long] = None

scala> val n = opt.getOrElse(0L)
n: Long = 0

scala> printInt(n)
0

getOrElse但是,如果我们将表达式嵌套在函数调用中,编译器会抛出类型不匹配错误:

scala> printInt(opt.getOrElse(0L))
<console>:16: error: type mismatch;
 found   : AnyVal
 required: Int
       printInt(opt.getOrElse(0L))
                             ^

为什么opt.getOrElse(0L)有类型 AnyVal?

斯卡拉 2.12.8

标签: scalatype-inferenceimplicit-conversion

解决方案


当你写

printInt(opt.getOrElse(0L))

opt.getOrElse(0L)使用预期类型键入IntOption#getOrElse的签名是

getOrElse[B >: A](default: ⇒ B): B 

因为它是通用的,所以编译器会尝试找到B具有opt.getOrElse[B](0L)type 的类型Int。所以B必须满足约束B >: Long(因为A在上面的签名中是Long)和B <: Int(来自返回类型)。显然没有这样的B。Scala规范说这一定是一个错误,但没有说是哪个,而这里编译器在猜测后恰好报告了它B = AnyVal

另一种解决方法是为 指定预期类型opt.getOrElse(0L)

printInt(opt.getOrElse(0L): Long)

或类型参数:

printInt(opt.getOrElse[Long](0L))

推荐阅读