6

这是一个简短的代码:

import scala.language.implicitConversions

implicit def str2int(str:String) = str.toInt

object Container {
  def addIt[A](x: A)(implicit str2int: A => Int) = 123 + x
  def addIt2(x: String)(implicit str2int: String => Int) = 123 + x
}

println(Container.addIt("123"));
println(Container.addIt2("123"));

两个问题:

  1. “(隐式str2int:A => Int)”称为视图吗?当您说“视图”时,它表示代码的哪个特定部分?
  2. 为什么 addIt 返回 246 而 addIt2 返回字符串“123123”?

任何关于这个主题的好资源也将不胜感激。谢谢你。

4

2 回答 2

4

View 意味着A可以将类型“查看”为类型B,由隐式函数指定A => B。所以,是的,隐含的论点addItaddIt2观点都是。

addIt2返回123123是因为(不幸的是)可以调用+两个对象,其中一个对象是 a String。这在 Scala 考虑应用str2int转换的可能性之前就开始了。如果您不希望这样,您可以显式应用视图:

def addIt2(x: String)(implicit str2int: String => Int) = 123 + str2int(x)

或者您可以隐藏 any2stringadd 转换:

object Container {
  import Predef.{any2stringadd => _}
  def addIt2(x: String)(implicit str2int: String => Int) = 123 + x
}
于 2013-07-02T09:17:17.657 回答
2
  1. 是的,它是一个隐式视图,但它并不表示代码的任何特定部分。它只是说类型 A 应该是“可转换的”,最好是隐式转换为 Int 类型,例如调用此方法时隐式转换器应该在范围内。

  2. 看起来当编译器翻译第一个方法时,它会看到 123.+(x:A) 并尝试找到“+”将编译的类型 A 的隐式。

然而,在第二种情况下,它看到 123.+(x:String) 并且在 Scala Predef 中有这样一个隐式转换。这实际上是 Scala 实现中的一个怪癖。隐式声明是:

final class StringAdd(self: Any) {
    def +(other: String) = self.toString + other
}

为了方便以前的 Java 开发人员使用类似的语法,它被留在 scala 中:123 + "something"并期望它是一个字符串。

于 2013-07-02T09:18:37.240 回答