隐式转换
隐式转换由 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[...]
参数的重载方法),或者如果普通重载会导致变体的组合爆炸,它仍然很有用。
本文中