Scala 隐含的意外行为

Scala 隐含的意外行为,scala,implicit,Scala,Implicit,昨天我遇到了一个奇怪的bug,最终我将其简化为以下代码: 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

昨天我遇到了一个奇怪的bug,最终我将其简化为以下代码:

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
欢迎使用Scala版本2.9.1.final(Java HotSpot(TM)64位服务器虚拟机,Java 1.6.029)。
键入要计算的表达式。
键入:有关详细信息的帮助。
scala>类X扩展函数[String,Int]{def apply(X:String)=Integer.parseInt(X)}
定义类X
scala>隐式val x=新x
x:x=
scala>“56”/2
res2:Int=28
我希望这会引发异常,因为字符串没有
/
方法。相反,Scala将隐式变量视为隐式方法(因为它实现了
函数[String,Int]
),并将字符串“56”转换为整数56


这是怎么回事?基于隐式搜索的规则,我认为不会考虑充当函数的隐式变量。

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

trait A
trait B

implicit def aToB(a : A) : B = new B {}
您将看到现在有一个隐式函数值
A=>B

scala> implicitly[A => B]
res1: A => B = <function1>

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

实际上,
隐式定义
转换是有效的,因为它会自动转换为函数值(即eta扩展).那么隐式方法是否简化为函数类型的隐式变量?或者Scala只处理这两种情况?在方法必须具体化为函数值(包括涉及视图边界的应用程序)的任何上下文中,是的。在我的示例中,如果您刚刚执行了(新的A{}:B),那么将应用该方法,而不首先实际创建函数对象,但是机制是相同的,因此您观察到的行为是相同的。
def foo[T <% B](t : T) : B = t
def foo[T](t : T)(implicit conv : T => B) : B = conv(t)