Scala中Option[T]链式隐式转换:Symbol转A再转Option[A]泛型实现问题
解决Symbol到Option[A]的隐式转换链问题
我来帮你梳理下这个隐式转换的问题——你想搭建一条Symbol -> A -> Option[A]的转换链,虽然现有代码能正常运行,但在泛型Option转换的实现上觉得不够优雅对吧?
先看你给出的示例代码:
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 // 返回Some(12)
这是因为Scala的隐式解析机制会自动串联转换:先通过toInt把Symbol转成Int,再匹配到toOptInt(因为存在Symbol => Int的隐式转换),最终生成Option[Int]。
不过你现在的写法有个问题:每新增一种目标类型(比如Double、Boolean),就得写一个对应的toOptXXX方法,重复代码太多。其实可以用泛型统一实现这个转换链,不用针对每种类型单独写转换:
// 基础转换:Symbol到String/Int implicit def symbolToString(n: Symbol): String = n.toString implicit def symbolToInt(n: Symbol): Int = n.toString.length // 通用的T到Option[A]隐式转换,只要存在T到A的隐式转换即可 implicit def toOption[A, T](value: T)(implicit converter: T => A): Option[A] = Option(converter(value))
这个通用版本的优势很明显:
- 不管你需要把
Symbol转成Option[String]、Option[Int]还是其他Option[A],只要存在Symbol -> A的基础隐式转换,就能自动完成整个链的转换 - 避免了重复编写类似
toOptStr、toOptInt这样的方法,代码更简洁易维护
测试一下这个通用实现:
val optStr: Option[String] = 'helloWorld // 结果:Some("'helloWorld") val optInt: Option[Int] = 'a25768xffff // 结果:Some(12)
如果之后需要支持Symbol转Option[Double],只需要新增一个Symbol -> Double的基础隐式转换就行,完全不用修改通用的toOption方法:
implicit def symbolToDouble(n: Symbol): Double = n.toString.length.toDouble val optDouble: Option[Double] = 'test // 结果:Some(6.0)
内容的提问来源于stack exchange,提问作者D. Kuzniatsou
相关产品推荐
相关产品推荐

