隐式转换,是否需要导入?

发布于 2024-10-09 16:43:55 字数 523 浏览 5 评论 0原文

我写

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 编程 中,我发现不需要导入源或预期目标类型的伴生对象中的隐式转换。

I write

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
    // ...
  }
}

in my program. This causes a compiling error. After I inserted

  import MyString.stringToMyString

Then it works.

From Odersky's Programming in Scala I got that implicit conversion in the companion object of the source or expected target types don't need to be imported.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

摘星┃星的人 2024-10-16 16:43:55

同伴中的隐式转换
来源或预期的对象
目标类型不需要是
导入。

确实如此。现在,方法 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 内)从 IntFraction 的隐式转换,如果有的话,因为那是源类型)。

implicit conversion in the companion
object of the source or expected
target types don't need to be
imported.

True enough. Now, the method camelize is defined on the class MyString, and, indeed, there is an implicit conversion to MyString inside its object companion. However, there is nothing in the code telling the compiler that MyString is the expected target type.

If, instead, you wrote this:

val x = ("active_record": MyString).camelize

then it would work, because the compiler would know you expect "active_record" to be a MyString, making it look up the implicit conversion inside object MyString.

This might look a bit restrictive, but it actually works in a number of places. Say, for instance, you had:

class Fraction(num: Int, denom: Int) {
    ...
    def +(b: Fraction) = ...
    ...
}

And then you had a code like this:

val x: Fraction = ...
val y = x + 5

Now, x does have a + method, whose expected type is Fraction. So the compiler would look, here, for an implicit conversion from Int to Fraction inside the object Fraction (and inside the object Int, if there was one, since that's the source type).

虚拟世界 2024-10-16 16:43:55

在这种情况下,您需要导入,因为编译器不知道您从哪里提取 camelize 方法。如果类型明确,它将在不导入的情况下进行编译:

object Parse {
  def foo(s: MyString) = s.camelize

  def main(args: Array[String]) {
    val x = foo("active_record")
    println(x.toString)
  }
}

请参阅 Pimp 我的库模式 ,基于 Martin 的文章

请注意,不可能将 def 放在顶层,因此您无法定义具有全局范围的隐式转换。解决办法就是把def放在一个对象里面,然后import它,即

object Implicits {
    implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs)
}

然后在每个源文件的顶部以及其他导入:

import Implicits._

In this situation you need the import because the compiler doesn't know where you pulled out the camelize method from. If the type is clear, it will compile without import:

object Parse {
  def foo(s: MyString) = s.camelize

  def main(args: Array[String]) {
    val x = foo("active_record")
    println(x.toString)
  }
}

See Pimp my library pattern, based on Martin's article:

Note that it is not possible to put defs at the top level, so you can’t define an implicit conversion with global scope. The solution is to place the def inside an object, and then import it, i.e.

object Implicits {
    implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs)
}

And then at the top of each source file, along with your other imports:

import Implicits._
蓝天 2024-10-16 16:43:55

我尝试了《Scala 编程》一书中的 Rational 类示例,在其伴生对象中放置了一个隐式方法:

object Rational {
  implicit def intToRational(num: Int) = 
    new Rational(num)
}

但代码

2 + new Rational(1, 2)

不起作用。为了发生转换,应用单一标识符规则,即,您需要将显式方法导入到作用域中,即使它是在伴生对象中定义的。

I tried the Rational class example in Programming in Scala book, put an implicit method in its companion object:

object Rational {
  implicit def intToRational(num: Int) = 
    new Rational(num)
}

but the code

2 + new Rational(1, 2)

does not work. For the conversion to happen, the single identifier rule applies, i.e., you need to import the explicit method into scope even though it is defined in the companion object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文