在 Scala 中以最干净的方式在字符串中使用 Option[string]?

Using Option[string] in a string the cleanest way in Scala?

我想知道这段代码是否:

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

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

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

我可以在不使用 getOrElse 的情况下使用字符串中的选项吗?

感谢您的输入:)

戴维

你可以定义一个"extension method":

implicit class StringOptionOps(val x: Option[String]) extends AnyVal {
  def getOrEmpty = x.getOrElse("")
  // any other methods you want to add to Option[String]
}

and/or customize string interpolation 根据需要处理 Options(未测试):

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 

这是 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: