【问题标题】:Understanding implicit conversions了解隐式转换
【发布时间】:2016-08-23 08:29:49
【问题描述】:

我正在阅读 Scala documentation 的隐式转换并决定尝试一下:

object Main extends App {
    val test = TestConversion(100)
    test.its
}

class Test[T](val t : T) {
  def its = println(t)
}

object Test {
  def apply[T](t: T): Test[T] = new Test(t)
}

class TestConversion(v : Int) {
  val value = v
}

object TestConversion{
  implicit def implicitConversionTest2Int(ict : TestConversion): Test[Int] = Test(ict.value)
  def apply(v : Int) = new TestConversion(v)
}

俗话说:

要定义自己的隐式转换,您必须首先导入 scala.language.implicitConversions(或调用编译器 -language:implicitConversions)。该功能必须显式启用,因为如果不加选择地使用它会有缺陷。

我在 IntelliJ 和在线 IdeOne 中都试过了,我没有添加任何特殊的东西来让它编译。

它带来了什么陷阱,为什么它在没有任何导入的情况下也能工作?

【问题讨论】:

  • 这是您正在阅读的一些旧东西。您无需导入任何内容即可使用隐式转换。您可能必须添加编译器标志,否则它会给您编译时警告
  • @sebszyller 但他们谈论的陷阱是什么?
  • 当你有很多隐含时,很难跟踪它们并推理代码。这就是通配符导入如果不谨慎进行如此危险的原因之一。

标签: scala implicit-conversion


【解决方案1】:

您无需导入任何内容。 这个想法是您可以在范围内的任何位置声明隐式转换函数。 例如:

case class Coins(amount:Int)
case class Bills(amount:Int)

object Main {
  implicit def billsToCoins(bills:Bills):Coins = Coins(bills.amount * 100)

  def printCoins(coins:Coins) = println(s"You have ${coins.amount} coins." )

  def main(args:Array[String]): Unit ={
    printCoins(Bills(3))
  }

}

我在这里声明了隐式函数billsToCoins,因此它在main 函数的范围内可用。函数作为隐式转换器唯一需要的是拥有implicit 修饰符,编译器会找到并使用它。您会看到printCoins 函数接受Coins 类型的参数,但我能够传递Bills 类型的值并且它已成功创建。 这是控制台输出:

You have 300 coins.

Process finished with exit code 0

【讨论】:

    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多