隐式转换
隐式转换由 scala.Conversion 类的给定实例定义。此类在包 scala 中定义如下
abstract class Conversion[-T, +U] extends (T => U):
def apply (x: T): U
例如,这里是从 String 到 Token 的隐式转换
given Conversion[String, Token] with
def apply(str: String): Token = new KeyWord(str)
使用别名可以更简洁地表示为
given Conversion[String, Token] = new KeyWord(_)
编译器在以下三种情况下自动应用隐式转换
- 如果表达式
e的类型为T,并且T不符合表达式的预期类型S。 - 在选择
e.m中,e的类型为T,但T未定义任何成员m。 - 在应用
e.m(args)中,e的类型为T,如果T定义了一些名为m的成员,但这些成员都不能应用于参数args。
在第一种情况下,编译器会查找给定的 scala.Conversion 实例,该实例将类型为 T 的参数映射到类型 S。在第二种和第三种情况下,它会查找给定的 scala.Conversion 实例,该实例将类型为 T 的参数映射到定义成员 m 的类型,如果存在,则可以将该成员应用于 args。如果找到这样的实例 C,则表达式 e 将替换为 C.apply(e)。
示例
-
Predef包含将基本数字类型映射到java.lang.Number子类的“自动装箱”转换。例如,从Int到java.lang.Integer的转换可以定义如下given int2Integer: Conversion[Int, java.lang.Integer] = java.lang.Integer.valueOf(_) -
“磁铁”模式有时用于表示方法的许多变体。与其定义方法的重载版本,还可以让方法采用一个或多个专门定义的“磁铁”类型的参数,各种参数类型都可以转换为该类型。示例
object Completions: // The argument "magnet" type enum CompletionArg: case Error(s: String) case Response(f: Future[HttpResponse]) case Status(code: Future[StatusCode]) object CompletionArg: // conversions defining the possible arguments to pass to `complete` // these always come with CompletionArg // They can be invoked explicitly, e.g. // // CompletionArg.fromStatusCode(statusCode) given fromString : Conversion[String, CompletionArg] = Error(_) given fromFuture : Conversion[Future[HttpResponse], CompletionArg] = Response(_) given fromStatusCode: Conversion[Future[StatusCode], CompletionArg] = Status(_) end CompletionArg import CompletionArg.* def complete[T](arg: CompletionArg) = arg match case Error(s) => ... case Response(f) => ... case Status(code) => ... end Completions
此设置比简单的 complete 重载复杂,但如果无法使用普通重载(如上例所示,因为我们不能有两个采用 Future[...] 参数的重载方法),或者如果普通重载会导致变体的组合爆炸,它仍然很有用。
本文中