我想知道这段代码是否可用:
val some = Some("string").getOrElse("")
val none = None.getOrElse("")
println(s"some $some none $none") -> some string none
可写得更干净吗?我主要看的是getOrElse部分。
我可以在字符串中使用选项而不必使用getOrElse吗?
感谢您的意见:)
戴维
答案 0 :(得分:3)
您可以定义"扩展方法":
implicit class StringOptionOps(val x: Option[String]) extends AnyVal {
def getOrEmpty = x.getOrElse("")
// any other methods you want to add to Option[String]
}
和/或customize string interpolation根据需要处理Option
(未经测试):
implicit class StringOptionInterp(val sc: StringContext) {
def my(args: Any*) = {
val args1 = args.map {
case None => ""
case Some(x) => x
case x => x
}
sc.s(args1: _*)
}
}
// println(my"some ${Some("string")} none $None") -> some string none
答案 1 :(得分:3)
这是对Alexey的解决方案的概括 - pimp-my-library 模式的应用。
通过轻微滥用CanBuildFrom
隐含,可以编写适用于包装集合类型的选项的通用扩展方法orEmpty
。
基本上需要的是一种获取某个包装类型的空实例的方法。这也可以使用scalaz中的Monoid.empty
来完成。 CanBuildFrom
解决方案的优势在于它不依赖外部依赖。
implicit class RichOpt[A](opt: Option[A]) {
import collection.generic.CanBuildFrom
def orEmpty[To >: A](implicit cbf: CanBuildFrom[A,_,To]): To =
opt.getOrElse(cbf().result())
}
//--------- Examples --------------
println("some seq: " + (None: Option[Seq[Int]]).orEmpty)
//>some seq: List()
println("none seq: " + (Some(Seq(1,2,3))).orEmpty)
//>none seq: List(1, 2, 3)
println("some range: " + (Some(1 to 3)).orEmpty)
//>some range: Range(1, 2, 3)
println("none range: " + (None: Option[Range]).orEmpty)
//>none range: Vector()
println("some string: " + Some("abc").orEmpty)
//>some string: abc
println("none string: " + (None: Option[String]).orEmpty)
//>none string: