我更愿意看到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()..
答案 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类支持类似的功能)