我最近使用了scala三元运算符的这个实现,尤其是切换启用/禁用图像,但是,我通常可以理解我发现的代码片段,这让我感到困惑。我也想稍微修改它以更好地满足我的需求。我喜欢运算符的语法,而不是详细的if else块等。
implicit def BooleanBool(b: Boolean): Bool = Bool(b)
case class Bool(b: Boolean) {
def ?[X](t: => X) = new {
def |(f: => X) = if (b) t else f
}
}
所以我理解隐式创建一个Bool对象,用?作为一个功能。该函数必须返回X类型的值。其余的我很难理解。
继承我的问题:
嵌套三元运算符是否存在缺点,例如:
isTheSkyBlue() ? goOutside() | {
isTheInternetOn() ? playVideoGame() | read()
}
是否可以将嵌套更改为case语句。即使用a =>运营商或类似的。例如
isTheSkyBlue() ? goOutside() | =>
isTheInternetOn() ? playVideoGame() | read()
甚至可以一起摆脱它
isTheSkyBlue() ? goOutside() |
isTheInternetOn() ? playVideoGame() | read()
答案 0 :(得分:3)
要回答1和2,嵌套函数非常简单,字符?
|
只是方法名称。我将?
重命名为question
,将|
重命名为or
,并将其添加到Bool
的显式调用中。这就像脱糖一样:
case class Bool(b: Boolean) {
def question[X](t: => X) = new {
def or(f: => X) = if (b) t else f
}
}
Bool(isTheSkyBlue()).question(goOutside()).or(
Bool(isTheInternetOn()).question(playVideoGame()).or(read())
)
3有点难度,因为if
需要else
,否则会返回什么?如果您只是做副作用,那么您可以这样做:
implicit def OneWayBooleanBool(b: Boolean): OneWayBool = OneWayBool(b)
case class OneWayBool(b: Boolean) {
def ??[X](t: => X) = if (b) t
}
isTheSkyBlue() ?? goOutside()
对于问题4,除了复杂的代码之外,嵌套没有真正的问题。
对于问题5,你无法真正做到这一点,因为scala将如何解决问题,除非其他人知道如何做到这一点。
答案 1 :(得分:1)
补充@Noah的回答:
?
函数没有返回类型X
的值,它返回一个匿名类。我们可以把它变成一个普通的班级(暂时忽略懒惰):
class PartiallyEvaluated[X](b: Boolean, t: X) {
def |(f: X) = if(b) t else f
}
class Bool(b: Boolean) {
def ?[X](t: X) = new PartiallyEvaluated(b, t)
}
Scala始终将a b c d e
解析为a.b(c).d(e)
。如果你愿意添加一个“结束链”方法,那么你可以让第一个表达式返回某种懒惰的东西,它知道在另一个对象上调用时该怎么做。或者你可以为这些东西的链做出for
/ yield
语法,但我怀疑这会比有用的更令人困惑。