在字符串中使用Option [string]是Scala中最干净的方法吗?

时间:2015-03-25 09:17:44

标签: scala string-formatting optional simplify

我想知道这段代码是否可用:

val some = Some("string").getOrElse("")
val none = None.getOrElse("")

println(s"some $some none $none") -> some string none 

可写得更干净吗?我主要看的是getOrElse部分。

我可以在字符串中使用选项而不必使用getOrElse吗?

感谢您的意见:)

戴维

2 个答案:

答案 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: