Scala链接意味着Option [T]的转换

时间:2018-04-25 13:27:53

标签: scala implicit-conversion

我尝试从Symbol - >创建隐式转换链。 A - >选项[A]。但未能使其与通用选项转换一起使用,例如:

implicit def toInt(n: Symbol): Int = n.toString.length
implicit def symbolToString(n: Symbol): String = n.toString
implicit def toOptStr[T](b: T)(implicit fn: T ⇒ String): Option[String] = Option(b)
implicit def toOptInt[T](b: T)(implicit fn: T ⇒ Int): Option[Int] = Option(b)

它运作良好:

val c: Option[Int] = 'a25768xffff // returns Some(12)
val d: Option[String] = 'a2699 // returns Some('a2699) 

但我必须明确定义toOptStr[T](b: T): Option[String]toOptInt[T](b: T)(implicit fn: T ⇒ Int): Option[Int]

我想要实现的目标只是进行一次通用toOptT转换,只要有来自Option[T]的隐式转换,就可以转换为T=>V,如下所示:

implicit def toInt(n: Symbol): Int = n.toString.length
implicit def symbolToString(n: Symbol): String = n.toString
implicit def toOptT[T,V](b: T)(implicit fn: T ⇒ V): Option[V] = Option(fn(b))

val c: Option[Int] = 'a25768xffff 
val d: Option[String] = 'a2699 

不幸的是,最后两行给出了编译错误:

Error:(34, 93) type mismatch;
   found   : Symbol
   required: Option[Int]
Error:(35, 96) type mismatch;
   found   : Symbol
   required: Option[String]

非常感谢任何帮助。

在Scala 12.2.5上尝试过。有一些相关问题:Chain implicit conversion of collection,链接含义详情常见问题解答:https://docs.scala-lang.org/tutorials/FAQ/chaining-implicits.html

1 个答案:

答案 0 :(得分:0)

无法在2.12.5上运行。

以下是一种可行的解决方法:

implicit val toInt: Symbol => Int = _.toString.length
implicit val symbolToString: Symbol => String = _.toString
implicit class ToOptOps[S](s: S) {
  def toOpt[T](implicit c: S => T): Option[T] = Option(c(s))
}

val c = 'a25768xffff.toOpt[Int]
val d = 'a2699.toOpt[String]

我建议你只使用类型类与隐式类结合使用" pimp-the-interface" (在这种情况下添加新方法,如toOpt)。在这里,实际应该用适当的类型类替换implicit c: S => T,以避免不必要的碰撞。类型类与" pimping"的结合已被证明是健壮的。与此相反,隐性转换似乎是邪恶的。