你如何以现代方式定义隐式转换?

时间:2011-11-18 13:15:59

标签: scala implicit implicit-conversion

愚蠢的问题,但这些例子都不适合我;经典文章“Pimp my Library”是错误的,即使是最简单的代码也存在问题。

顺便说一下。我假设您必须在对象中放置转换方法(很多片段都省略了该部分)。根据PiS的书,似乎挂隐式def是可以的,但这也给了我错误。

object Minutes
{
  implicit def toMinutes(x : Int) = new Minutes(x)
}

class Minutes(private val x : Int)
{
  def minutes = x.toString+"m"
}

object MainApp {

  def main(args : Array[String])
  {
     println(5.minutes)
     ...

错误 - “值分钟不是Int的成员”。

问题

我错过了什么? Scala 2.9.1。

3 个答案:

答案 0 :(得分:9)

您需要做的就是将隐式转换带到您想要使用它的范围内,以便编译器可以找到它......

def main(args : Array[String]) {
   import Minutes._
   println(5.minutes)
}

答案 1 :(得分:7)

隐式转换必须在范围内,例如

def main(args : Array[String]) {
  import Minutes._
  println(5.minutes)
  ...
}

还有其他方法,例如使用包对象。

答案 2 :(得分:1)

您可以在 Pimp my library 文章中获取示例,如下所示:

class RichArray[T: Manifest](value: Array[T]) {
  def append(other: Array[T]): Array[T] = {
    val result = new Array[T](value.length + other.length)
    Array.copy(value, 0, result, 0, value.length)
    Array.copy(other, 0, result, value.length, other.length)
    result
  }
}

implicit def enrichArray[T: Manifest](xs: Array[T]) = new RichArray[T](xs)

T需要上下文绑定[T: Manifest][T](implicit m: Manifest[T])的缩写。当T已知时,Manifest是一种在运行时将T的值传递给方法的方法。通常,编译器使用参数化类型信息来确保编译时的类型安全性,但未将其合并到字节码中,因为JVM无法处理它(类型擦除)。 Scala集合在版本2.8中已更改,因此出于性能原因,Arrays现在不会被编译器魔术自动包装,因此为通用操作提供清单变得必要。

另一个变化是(xs)的{​​{1}}参数。我认为这是一个错字。