我尝试从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
答案 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"的结合已被证明是健壮的。与此相反,隐性转换似乎是邪恶的。