我曾在Scala示例中看到过一个名为implicitly
的函数。它是什么,如何使用?
scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
| implicit def stringImpl = new Foo[String] {
| def apply(list : List[String]) = println("String")
| }
| implicit def intImpl = new Foo[Int] {
| def apply(list : List[Int]) = println("Int")
| }
| } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit
scala> foo(1)
<console>:8: error: type mismatch;
found : Int(1)
required: List[?]
foo(1)
^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
Foo[Double]
foo(List(1.0))
^
请注意,我们必须写成
implicitly[Foo[A]].apply(x)
,因为编译器认为implicitly[Foo[A]](x)
表示我们用参数调用implicitly
。另请参见如何从Scala REPL中调查对象/类型等?和Scala在哪里查找隐式转换?。
Ordering
类型类来比较元组(Int, String)
的顺序。通过上下文界定语法,我们可以将Ordering[(Int, String)]
隐式地传递给implicitly
函数,然后使用.compare()
方法比较元组。另外,当定义一个函数foo[A: Ordering]
时,我们也可以使用上下文界定来引入Ordering
类型类,并使用implicitly
函数来检索它,以对类型A
进行比较操作。 - retronym