【问题标题】:Unexpected behavior with implicits隐含的意外行为
【发布时间】:2012-03-07 17:47:30
【问题描述】:

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

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

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

这是如何工作的?根据隐式搜索的规则,我认为不会考虑充当函数的隐式变量。

【问题讨论】:

  • 实际上,implicit def 转换是有效的,因为它会自动转换为函数值(即 eta 扩展)。

标签: scala implicit


【解决方案1】:

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

trait A
trait B

implicit def aToB(a : A) : B = new B {}

你会看到你现在有一个隐式函数值A =&gt; B

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

如果你有一个绑定视图的方法,

def foo[T <% B](t : T) : B = t

这相当于,

def foo[T](t : T)(implicit conv : T => B) : B = conv(t)

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

【讨论】:

  • 那么隐式方法是否简化为 Function 类型的隐式变量?还是 Scala 只处理这两种情况?
  • 在任何必须将方法具体化为函数值的上下文中(包括涉及视图边界的应用程序),是的。在我的示例中,如果您刚刚执行了 (new A {} : B),则将应用该方法而无需首先实际创建函数对象,但机制是相同的,因此您观察到的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2016-07-16
相关资源
最近更新 更多