【问题标题】:Test if implicit conversion is available测试隐式转换是否可用
【发布时间】:2011-04-19 14:21:19
【问题描述】:

我正在尝试检测是否存在隐式转换,并根据它来执行一些代码。例如:

if (x can-be-converted-to SomeType)
  return something(conversion(x))
else
  return someotherthing(x)

例如,x 是一个 Int,应该转换为 RichInt。 这在 Scala 中可行吗?如果是,怎么做?

谢谢

【问题讨论】:

  • 隐式转换仅存在于编译时而不存在于运行时。如果你想测试是否存在这样的转换,你可以写下代码并尝试编译它。编译器会告诉你是否可以编译。

标签: scala implicit-conversion


【解决方案1】:

正如其他人已经提到的那样,隐式在编译时解决,所以也许你应该使用类型类来解决这样的问题。这样一来,您就可以在以后将功能扩展到其他类型。

您也可以只需要一个现有的隐式值,但无法直接表示除默认参数外不存在隐式值。

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[Boolean, Ordered[Boolean]]”进行测试时,它返回 false。我以为会使用到 RichBoolean 的转换,但似乎没有。怎么了?
  • 如果没有代码,我将不得不猜测:可能你用括号这样称呼它:canConvert[Boolean,Ordered[Boolean]]()。然后编译器填充默认参数 - 这不是您想要的。从调用中删除括号或在隐式参数之前添加一个空参数列表。
  • @saucisson 我更新了代码以包含一个空参数列表 - 现在无论您调用 canConvert 方法是否包含空参数列表都无关紧要。
【解决方案2】:

您可以尝试将其传递给需要相应隐式参数的方法,默认为null

def toB[A](a: A)(implicit convertFct: A => B = null) =
  if (convertFct != null)
    convertFct(a)
  else
    someOtherThing(a)

请注意,我觉得在运行时检查它看起来很奇怪,因为编译器在编译时就知道这样的转换函数是否可用。

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多