假设我想将任何可隐式转换为Double
的东西划分为:
def divide[T](a: T, b: T)(implicit ev: T => Double) = a / b
divide(1, 2)
// 0.5
字符串
然而,(1)这不会对String开箱即用,(2)试图提供隐式转换,如:
implicit def string2double(a: String): Double = a.toDouble
型
会失败:
cell3.sc:3: type mismatch;
found : a.type (with underlying type String)
required: ?{def toDouble: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method augmentString in object Predef of type (x: String): scala.collection.StringOps
and method string2double in class Helper of type (a: String): Double
are possible conversion functions from a.type to ?{def toDouble: ?}
implicit def string2double(a: String): Double = a.toDouble
^
cell3.sc:3: value toDouble is not a member of String
implicit def string2double(a: String): Double = a.toDouble
^
Compilation Failed
型
为什么不使用现成的转换,以及如何将T
也推广到字符串?
1条答案
按热度按时间kx5bkwkv1#
当然,您最了解您的具体用例,但我认为值得指出的是,使用隐式转换可能会有意想不到的陷阱,特别是在广泛使用的
Double
和String
类型上使用时:https://www.scala-lang.org/api/2.13.12/scala/language $.html#implicitConversions:languageFeature.implicitConversions例如,请注意,
toDouble
实际上并不是在String
上定义的,而是在一个隐式类上定义的,该类通过隐式转换 Package 在java.lang.String
周围:https://www.scala-lang.org/api/2.13.12/scala/collection/StringOps.html#toDouble:Double如果您仍然认为使用隐式转换是您的用例的最佳操作过程,您可以显式地将
String
Package 在StringOps
Package 器中,以避免编译器产生一些混乱。以下工作原理:字符串
你可以使用这个代码here on Scastie。
至于为什么你的尝试不起作用,我最好的猜测是(但要持保留态度,并与真正了解Scala编译器的人进行验证)编译器进行隐式转换,在此期间隐式转换对代码不可用,使得“递归隐式转换”不可能。