【问题标题】:Implicit conversions in scalascala中的隐式转换
【发布时间】:2017-06-28 15:34:20
【问题描述】:

Scala 是否有对象的隐式转换?例如,如果我有一个具有以下签名的方法:

object Foo {
  def print(message: String) = println(message)
}

class Bar {
    val baz = 1
}

如何拨打Foo.print(new Bar)

我可以在Bar 类上放置一个方法来将Bar 实例隐式转换为字符串,而不必在参数中调用toString

C# 有这个,我想知道 scala 是否也有。

假设我们有 Scala 枚举:

object Color extends Enumeration {

  type Method = Value

  val RED, BLUE, GREEN = Value

 }

那我有课了:

object ColorPrinter {
  def print(x: String) = {
    println(x)
  }
}

ColorPrinter 的打印方式无法更改。

我想打电话给ColorPrinter.print(Color.RED),但我不能这样做。我必须这样称呼它:ColorPrinter.print(Color.RED.toString)

我想避免toString

【问题讨论】:

  • 出于可读性原因,通常不鼓励使用隐式自动全局转换

标签: scala


【解决方案1】:

将事物隐式转换为基本类型,例如 StringInt 并不是一个好主意(隐式转换可能会在您不希望发生的地方触发,从而产生微妙的、难以调试的问题)。

为什么不直接说清楚呢? ?

class Bar {
   val baz = 1
   def print = Foo.print(toString)
}

new Bar().print

【讨论】:

    【解决方案2】:

    您可以将可以自动应用的隐式转换放入类的伴随对象中:

    class Bar {
      val baz = 1
    }
    
    // This should be the companion object of `Bar`, so if in console, use :paste mode
    object Bar {
      implicit def toString(bar: Bar): String = bar.toString
    }
    
    scala> Foo.print(new Bar) // works without `import Bar._`
    $line7.$read$$iw$$iw$Bar@280ecc33
    

    对于Enumerations,您可以将转换放入对象本身:

    object Color extends Enumeration {
    
      type Method = Value
    
      val RED, BLUE, GREEN = Value
    
      implicit def toString(value: Value): String = value.toString 
    }
    
    scala> ColorPrinter.print(Color.RED) // works without `import Color._`
    RED
    

    您可以在此答案中阅读有关 Scala 中隐式解析的更多信息:https://stackoverflow.com/a/5598107/1098230

    【讨论】:

      【解决方案3】:

      这是一个典型的方法, 是的,Implicit 与 C# 的静态方法非常相似,并且是以 adhoc 方式实现的:

      object Foo {
        def print(message: String) = println(message)
      }
      
      class Bar {
        val baz = 1
      }
      
      object BarToStringMaker {
         implicit def barToString(b : Bar) : String = b.baz.toString
      }
      
      import BarToStringMaker._
      
      Foo.print(new Bar)
      

      更多阅读:

      http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html

      希望对你有帮助,

      【讨论】:

      • 同意,可能误解了书中的内容,它不是对 C# 更改的响应,更新了我的答案。
      • 伴随对象中定义的隐式不需要显式导入。转换为字符串是一个非常糟糕的主意。打印方法与 println 没有什么不同。
      • @flavian 打印方法只是降低复杂性。我的用例比 println 的简单包装器更复杂
      • @RyanMcCullagh 你能发布一个更现实的场景,也许我们可以更有帮助吗?
      猜你喜欢
      • 2018-09-16
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 2019-04-01
      • 1970-01-01
      相关资源
      最近更新 更多