在scala中覆盖Option [_]的toString行为

时间:2013-12-14 18:22:37

标签: scala scala-option

我更愿意看到Option的值(如果它不是None),而不是以下额外的Some()噪声:

List((Some(OP(_)),Some(share),3), (Some(OP(D)),Some(shaara),4), (Some(OP(I)),Some(shaaee),4))

现在,我可以编写一个处理List [Option [_]]的方法。但是还有很多其他结构可以出现 - 所以这种明确解决每个结构的方法都很麻烦。

由于含义优先级较低,以下代码只会被忽略:

  implicit def toString(myopt : Option[_]) = if (myopt == None) "None" else myopt.get

值得关注的是 - 尽管实现了例如以所需方式处理此问题的toString(List [Option_]])方法,但这仍然是一次性的。

怎么样?
Map[Option,Option]  =>     def toString(Map[Option,Option]) = { .. }

似乎我们仍然需要为每个集合类型实现一个显式的toString()..

3 个答案:

答案 0 :(得分:4)

我想您无法覆盖toString的此行为,但您可以使用scalaz中的shows(和show)方法。您可以覆盖这些方法的行为:

import scalaz._, Scalaz._
val l = List(1.some, none, 3.some, 4.some, none, 6.some)

l.shows
// res0: String = [Some(1),None,Some(3),Some(4),None,Some(6)]

implicit def optionShow[T: Show]: Show[Option[T]] =
  Show.show{ _.map{_.show}.getOrElse(Cord("<none>")) }

l.shows
// res1: String = [1,<none>,3,4,<none>,6]

适用于Show的所有类型:

1.some.node(none.node(2.some.leaf)).drawTree
// 1
// |
// `- <none>
//    |
//    `- 2

Map(1.some -> 2.some, none[Int] -> 3.some).shows
// Map[1->2, <none>->3]

答案 1 :(得分:2)

好吧,我会写一个类似于你隐含的Wrapper。

class OW[T](val option : Option[T]) {
  override def toString = if (option.isEmpty) "None" else option.get.toString
}

然后,当我想要漂亮的toString时,我只会将任何集合映射到OW的实例。

println(List(Some(3), Some("Hello"), None).map(new OW(_)))

打印:List(3,Hello,None)

不要真的看到更好的方法。

答案 2 :(得分:0)

以下照顾到我想到的案例:

  def show(obj: Any) : String = {
    obj match {
      case o: Option[_] =>
        if (o == None) {
          "<none>"
        } else {
          show(o.get)
        }
      case i: Iterable[_] =>
        i.map(show).mkString("[", ",", "]")
      case m: Map[_, _] =>
        m.map {
          case (a, b) => List(show(a), show(b)).mkString(":")
        }.mkString("{", ",", "}")
      case e: Enumeration =>
        e.toString
      case c : Product if !c.getClass.getMethods.map(_.getName).contains("copy$default$2") =>
        c.toString
      case t: Product =>
        t.productIterator.map(a => show(a)).mkString("(", ",", ")")
      case _ =>
        if (obj.isInstanceOf[AnyRef])
          obj.asInstanceOf[AnyRef].toString
        else
          "" + obj
    }
  }

我选择对其进行编码以避免添加scalaz依赖(假设他们的Show类支持类似的功能)