我试图检测隐式转换是否存在,并根据它执行一些代码。例如:测试隐式转换是否可用
if (x can-be-converted-to SomeType)
return something(conversion(x))
else
return someotherthing(x)
例如,x是一个Int,应该转换为RichInt。 这可能在斯卡拉?如果是,如何?
感谢
我试图检测隐式转换是否存在,并根据它执行一些代码。例如:测试隐式转换是否可用
if (x can-be-converted-to SomeType)
return something(conversion(x))
else
return someotherthing(x)
例如,x是一个Int,应该转换为RichInt。 这可能在斯卡拉?如果是,如何?
感谢
正如其他人已经提到implicits在编译时间,所以也许你应该宁愿用类型类来解决这样的问题解决了。这样你就可以将功能扩展到其他类型。
您也可以只需要现有的隐含价值,但没有直接表达的隐含价值不存在除了默认参数的方式。
Jean-Phiippe使用默认参数的解决方案已经相当不错了,但如果您定义了一个可替代隐式参数的单例,则可以取消null
。将它设为私有是因为它在其他代码中实际上没有用处,甚至可能是危险的,因为隐式转换可能会隐式发生。
private case object NoConversion extends (Any => Nothing) {
def apply(x: Any) = sys.error("No conversion")
}
// Just for convenience so NoConversion does not escape the scope.
private def noConversion: Any => Nothing = NoConversion
// and now some convenience methods that can be safely exposed:
def canConvert[A,B]()(implicit f: A => B = noConversion) =
(f ne NoConversion)
def tryConvert[A,B](a: A)(implicit f: A => B = noConversion): Either[A,B] =
if (f eq NoConversion) Left(a) else Right(f(a))
def optConvert[A,B](a: A)(implicit f: A => B = noConversion): Option[B] =
if (f ne NoConversion) Some(f(a)) else None
感谢您的回答。当使用“canConvert [布尔,有序[布尔]]”进行测试时,它返回false。我认为将会使用转换为RichBoolean,但似乎没有。哪里不对? – 2011-04-21 07:44:04
如果没有代码,我将不得不猜测:可能你用括号调用它:'canConvert [Boolean,Ordered [Boolean]]()'。编译器然后填入默认参数 - 这不是你想要的。从调用中删除括号或在隐式参数之前添加一个空参数列表。 – Moritz 2011-04-21 11:38:45
@saucisson我更新了代码以包含一个空的参数列表 - 现在如果您调用具有或不具有空参数列表的'canConvert'方法并不重要。 – Moritz 2011-04-21 12:02:13
你可以尝试将它传递给需要相应的隐含参数与null
默认的方法:
def toB[A](a: A)(implicit convertFct: A => B = null) =
if (convertFct != null)
convertFct(a)
else
someOtherThing(a)
注意,它看起来好奇,我在运行时检查这一点,因为编译器在编译时知道这样的转换函数是否可用。
隐式转换仅在编译时和不存在的在运行时。如果你想测试这种转换是否存在,你可以写下代码并尝试编译它。编译器会告诉你它是否可以编译。 – sschaef 2011-04-19 14:30:37