gpt4 book ai didi

scala - Scala 中非 boolean 类型的逻辑运算符

转载 作者:行者123 更新时间:2023-12-05 00:31:26 24 4
gpt4 key购买 nike

我喜欢在 Lisp、Python 或 JavaScript 等(通常是动态的)语言中可以使用 boolean 运算符而不是条件来编写的简洁代码,如典型的:

x = someString or "default string"

对比
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类型?
  • 这太酷了,以至于其他人之前肯定已经做过了,可能是在一个更好的文档化、测试和全面的库中。在哪里可以找到它?
  • 最佳答案

    我会坚持使用 Option[T]... 这对 Scala 来说更惯用。我也经常在验证中使用它,例如:在 Web 表单中,有时不应将空字符串视为有效的用户输入。

    例如,如果您认为长度为零的空字符串/字符串 ( "" ) 为假,则任何空引用也是假的,任何数字零也是假的,您可以编写以下隐式 defs。

    object MyOptionConverter
    {
    implicit def toOption(any: AnyRef) = Option(any)
    implicit def toOption(str: String) = {
    Option(str).filter(_.length > 0)
    }

    implicit def toOption[T](value: T)(implicit num: Numeric[T]): Option[T] = {
    Option(value).filter(_ != 0)
    }
    }

    import MyOptionConverter._

    println(1 getOrElse 10) // 1
    println(5.5 getOrElse 20) // 5.5
    println(0 getOrElse 30) // 30
    println(0.0 getOrElse 40) // 40
    println((null: String) getOrElse "Hello") // Hello
    println((null: AnyRef) getOrElse "No object") // No object
    println("World" getOrElse "Hello")

    如果您确实需要定义自己的运算符,请将其转换为包含 Option[T] 的类,并为其添加运算符。
    object MyOptionConverter
    {
    class MyBooleanLogic[T](x: Option[T], origin: T)
    {
    def |||(defaultValue: T) = x.getOrElse(defaultValue)
    def &&&(defaultValue: T) = x.isDefined match {
    case true => defaultValue
    case false => origin
    }
    }

    implicit def toOption(any: AnyRef) = {
    new MyBooleanLogic(Option(any), any)
    }
    implicit def toOption(str: String) = {
    new MyBooleanLogic(Option(str).filter(_.length > 0), str)
    }

    implicit def toOption[T](value: T)(implicit num: Numeric[T])= {
    new MyBooleanLogic(Option(value).filter(_ != 0), value)
    }
    }

    import MyOptionConverter._

    println(1 ||| 10) // 1
    println(5.5 ||| 20) // 5.5
    println(0 ||| 30) // 30
    println(0.0 ||| 40) // 40
    println((null: String) ||| "Hello") // Hello
    println((null: AnyRef) ||| "No object") // No object
    println("World" ||| "Hello")


    println(1 &&& 10) // 10
    println(5.5 &&& 20) // 20
    println(0 &&& 30) // 0
    println(0.0 &&& 40) // 0.0
    println((null: String) &&& "Hello") // null
    println((null: AnyRef) &&& "No object") // null
    println("World" &&& "Hello") // Hello

    关于scala - Scala 中非 boolean 类型的逻辑运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14822317/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com