我喜欢使用布尔运算符编写简洁的代码,而不是在(通常是动态)语言中使用条件语句来编写代码,比如Lisp、Python或JavaScript中的典型方式:
x = someString or "default string"
vs
if someString:
x = someString
else:
x = "default string"
在Scala中,我想到了以下内容:
object Helpers {
case class NonBooleanLogic[A](x: A) {
// I could overload the default && and ||
// but I think new operators are less 'surprise prone'
def |||(y: => A)(implicit booleanConversion: A => Boolean) = if (x) x else y
def &&&(y: => A)(implicit booleanConversion: A => Boolean) = if (!x) x else y
}
implicit def num2bool(n : Int) = n != 0
implicit def seq2bool(s : Seq[Any]) = !s.isEmpty
implicit def any2bool(x : Any) = x != null
implicit def asNonBoolean[T](x: T) = NonBooleanLogic(x)
}
object SandBox {
// some tests cases...
1 ||| 2 //> res2: Int = 1
val x : String = null //> x : String = null
x ||| "hello" //> res3: String = hello
//works promoting 2 to Float
1.0 &&& 2 //> res4: Double = 2.0
//this doesn't work :(
1 &&& 2.0
}
但是有两个问题:
- 如何使其适用于具有共同祖先的类型,而不会回到
Any
类型? - 这太酷了,肯定有其他人做过这件事,可能在一个更好的文档、测试和全面的库中。在哪里可以找到它?
val x = if (someString != null && someString.size() > 0) someString else "default string";
- Tomasz Nurkiewiczval x = Option(someString).filterNot(_.isEmpty).getOrElse("default string")
或者val x = if(someString != null && someString.size() > 0) someString else "default string"
。 - om-nom-nom