带有implicits的意外行为

Bil*_*ill 6 scala implicit

昨天我有一个奇怪的错误,我最终缩减为以下代码:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class X extends Function[String, Int] { def apply(x: String) = Integer.parseInt(x) }
defined class X

scala> implicit val x = new X
x: X = <function1>

scala> "56" / 2
res2: Int = 28
Run Code Online (Sandbox Code Playgroud)

我希望这会引发异常,因为String没有/方法.相反,Scala将隐式变量视为隐式方法(因为它实现Function[String,Int])并将字符串"56"转换为整数56.

这是如何运作的?基于隐式搜索的规则,我不认为将充当函数的隐式变量.

Mil*_*bin 7

隐式转换的语义正是您所观察到的.如果通过隐式方法定义隐式转换,

trait A
trait B

implicit def aToB(a : A) : B = new B {}
Run Code Online (Sandbox Code Playgroud)

你会看到你现在有一个隐含的函数值A => B,

scala> implicitly[A => B]
res1: A => B = <function1>
Run Code Online (Sandbox Code Playgroud)

并且你有一个带有视图绑定的方法,

def foo[T <% B](t : T) : B = t
Run Code Online (Sandbox Code Playgroud)

这相当于,

def foo[T](t : T)(implicit conv : T => B) : B = conv(t)
Run Code Online (Sandbox Code Playgroud)

即.对应于视图边界的隐式参数与隐式方法定义生成的隐式函数值具有完全相同的形式.