我写
object MyString {
implicit def stringToMyString(s: String) = new MyString(s)
}
class MyString(str: String) {
def camelize = str.split("_").map(_.capitalize).mkString
override def toString = str
}
object Parse {
def main(args: Array[String]) {
val x = "active_record".camelize
// ...
}
}
在我的程序中。这会导致编译错误。我插入后
import MyString.stringToMyString
然后它有效。
来自Odersky的 Scala编程我在源的伴随对象中得到了隐式转换,或者不需要导入预期的目标类型。
答案 0 :(得分:16)
随播中的隐式转换 来源或预期的对象 目标类型不需要 导入。
真的。现在,方法camelize
在类MyString
上定义,实际上,在其对象伙伴中有一个隐式转换为MyString
。但是,代码中没有任何内容告诉编译器MyString
是期望的目标类型。
相反,如果你写了这个:
val x = ("active_record": MyString).camelize
然后它会工作,因为编译器会知道你期望 "active_record"
是MyString
,使它在对象MyString
内查找隐式转换
这可能看起来有点限制,但实际上它可以在很多地方使用。比方说,你有:
class Fraction(num: Int, denom: Int) {
...
def +(b: Fraction) = ...
...
}
然后你有一个像这样的代码:
val x: Fraction = ...
val y = x + 5
现在,x
确实有+
方法,其预期类型为Fraction
。因此编译器会在这里查看对象Int
内部Fraction
到Fraction
的隐式转换(如果有的话,那么在对象Int
内部,因为那是来源类型)。
答案 1 :(得分:13)
在这种情况下,您需要导入,因为编译器不知道从哪里提取camelize
方法。如果类型是明确的,它将编译而不导入:
object Parse {
def foo(s: MyString) = s.camelize
def main(args: Array[String]) {
val x = foo("active_record")
println(x.toString)
}
}
根据Pimp my library pattern见<{3}}:
请注意,无法将defs置于顶层,因此您无法使用全局范围定义隐式转换。解决方案是将def放在一个对象中,然后导入它,即
object Implicits {
implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs)
}
然后在每个源文件的顶部,以及其他导入:
import Implicits._
答案 2 :(得分:0)
我在Scala编程书中尝试了Rational类示例,在其伴随对象中放入了一个隐式方法:
object Rational {
implicit def intToRational(num: Int) =
new Rational(num)
}
但是代码
2 + new Rational(1, 2)
不起作用。为了进行转换,应用单个标识符规则,即,即使在伴随对象中定义了显式方法,也需要将显式方法导入范围。