简体   繁体   English

Scala中的隐式转换

[英]Implicit conversions in scala

Does Scala have implicit conversions for objects? Scala是否有对象的隐式转换? For example, if I have a method with the following signature: 例如,如果我有一个带有以下签名的方法:

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

class Bar {
    val baz = 1
}

How can I call Foo.print(new Bar) ? 我怎么称呼Foo.print(new Bar)

Can I put a method on the Bar class to implicitly convert Bar instance to a string without having to call toString in the argument? 我可以在Bar类上放置一个方法以隐式将Bar实例转换为字符串,而不必在参数中调用toString吗?

C# has this and I'm wondering if scala does too. C#有这个,我想知道scala是否也有。

Let's say we have Scala enum: 假设我们有Scala枚举:

object Color extends Enumeration {

  type Method = Value

  val RED, BLUE, GREEN = Value

 }

Then I have a class: 然后我有一个课:

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

ColorPrinter's print method can't be changed. ColorPrinter的打印方法无法更改。

I want to call into ColorPrinter.print(Color.RED) , but I can't do that. 我想调用ColorPrinter.print(Color.RED) ,但是我做不到。 I would have to call it like this: ColorPrinter.print(Color.RED.toString) . 我必须这样称呼它: ColorPrinter.print(Color.RED.toString)

I want to avoid having to toString 我想避免不得不toString

Converting things implicitly to basic types, like String or Int isn't really a very good idea (the implicit conversion may trigger in places where you do not expect it to, creating subtle, hard to debug, issues). 将事物隐式转换为基本类型,例如StringInt并不是一个好主意(隐式转换可能会在您不期望的地方触发,从而产生细微,难以调试的问题)。

Why not just make it explicit? 为什么不将其明确化? ?

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

new Bar().print

You can put implicit conversions that can be applied automatically without importing into the companion object of the class: 您可以放置​​隐式转换,这些转换可以自动应用而无需导入类的伴随对象中:

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

For Enumeration s you can put conversions into the object itself: 对于Enumeration您可以将转换放入对象本身:

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

You can read more about implicit resolution in Scala in this answer: https://stackoverflow.com/a/5598107/1098230 您可以在以下答案中详细了解Scala中的隐式分辨率: https : //stackoverflow.com/a/5598107/1098230

Here is a typical approach, yes, Implicit's very similar to C# static methods and its implemented in adhoc way: 这是一种典型的方法,是的,隐式与C#静态方法非常相似,并且以即席方式实现:

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)

more reading: 更多阅读:

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

hope that helps, 希望能有所帮助,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM