假设我有几个功能:
func1 : A => B
func2: B => C
func3: C => D
我想以通用方式在需要时协调现在的功能。
让我们说如果我需要从A
转换为B
,我会调用func1
。
但是当我需要从A
转换为D
时,我希望得到这些功能的组合。在动态的概念中,这样的事情是否可能?
答案 0 :(得分:4)
来自Scala documentation for language features,解释为什么必须在2.10中明确启用隐式转换:
为什么要控制它?众所周知,隐式转换会导致许多陷阱 如果过度使用。并且有过度使用它们的倾向,因为它们 看起来非常强大,它们的效果似乎很容易理解。 此外,在大多数情况下使用隐式参数会带来更好的效果 设计而不是隐式转换。
用户定义的隐式转换几乎总是一个坏主意,并且使它们传递会更糟糕。
但是,您可以使用类型类以更安全,更受控制的方式获得类似的效果。例如,假设我们有以下内容:
trait MyConverter[A, B] { def apply(a: A): B }
implicit def composeMyConverters[A, B, C](implicit
ab: MyConverter[A, B],
bc: MyConverter[B, C]
) = new MyConverter[A, C] { def apply(a: A) = bc(ab(a)) }
现在我们可以写:
implicit object doubleToString extends MyConverter[Double, String] {
def apply(d: Double) = d.toString
}
implicit object intToDouble extends MyConverter[Int, Double] {
def apply(i: Int) = i.toDouble
}
def convertToString[A](a: A)(implicit as: MyConverter[A, String]) = as(a)
最后:
scala> convertToString(13: Int)
res0: String = 13.0
我们从未明确定义从整数到字符串的转换器,但编译器能够在需要时使用我们的composeMyConverters
方法构造一个。
与隐式转换一样,这种方法也可能会被滥用,但要更清楚地了解转换器的范围,应用位置等等。