三元运算符输入
我实现了一个三元运算符,如 Java 的
,用 /
替换 :
,因为 :
不是有效的标识符:
case class Ternary[T](val o: Option[T]) {
def / (f: => T) = o getOrElse f
}
implicit def boolToTernary(cond: Boolean) = new {
def ? [T](f: => T) = if(cond) Ternary(Some(f))
else Ternary[T](None)
}
一般情况下工作正常,例如
scala> (1 > 2) ? "hi" / "abc"
res9: java.lang.String = abc
,但在以下情况下会失败:
scala> (1 > 2) ? 5 / 6.0
<console>:33: error: type mismatch;
found : Double(6.0)
required: Int
(1 > 2) ? 5 / 6.0
^
是否可以对类型进行任何调整,以便使其像内置 if (1 > 2) 5 else 6.0
一样工作?我在谷歌上搜索了类似的解决方案,发现所有的实现都表现出相同的行为。
I implemented a ternary operator like Java's <condition> ? <if true> : <if false>
, substituting /
for :
, since :
is not a valid identifier:
case class Ternary[T](val o: Option[T]) {
def / (f: => T) = o getOrElse f
}
implicit def boolToTernary(cond: Boolean) = new {
def ? [T](f: => T) = if(cond) Ternary(Some(f))
else Ternary[T](None)
}
It works fine in general, e.g.
scala> (1 > 2) ? "hi" / "abc"
res9: java.lang.String = abc
but falls down in the following case:
scala> (1 > 2) ? 5 / 6.0
<console>:33: error: type mismatch;
found : Double(6.0)
required: Int
(1 > 2) ? 5 / 6.0
^
Is there any tweaking I can do to the types in order to get this to work like the built-in if (1 > 2) 5 else 6.0
does? I googled for similar solutions and the implementations I found all exhibited the same behaviour.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以做的一件事是将
/
的定义更改为:它不像常规
if
那样工作(其中推断类型为Double) — 您得到
AnyVal
,但这已经是一项改进,只需对代码进行很小的修改。更新:我想我已经找到了一种(稍微复杂一些)方法,使其表现得更像正常的 if (例如,在本例中,推断
Double
)。试试这个代码:然后(一些示例代码):
One thing you can do is change your definition of
/
to this:It doesn't work like a regular
if
(where the inferred type would beDouble
) — you getAnyVal
, but that's already an improvement with a very small modification to your code.Update: I think I've found a (slightly more complicated) way to make it behave more like a normal if (e.g., in this case, inferring a
Double
). Try this code:Then (some sample code):
这是我的版本只是因为我很好奇。我不会真正使用这个...
我选择了低优先级运算符。
^
将首先绑定,然后是|?
。我利用元组是协变的事实来推断结果的类型。另一个例子展示了运算符优先级如何协同工作:
可能需要做一些工作来确保未使用的分支不会被评估。
仅供思考:请注意,调用函数时类型推断会做正确的事情。不太灵活的语法适合您吗?它确实简单得多...
此外,这在 scalaz 中可用,但他们将其命名为
fold
:Here is my version just cause I'm curious. I wouldn't really use this...
I chose low priority operators.
^
will bind first, then|?
. I use the fact that tuples are covariant to infer the type of the result.Another example showing how operator precedence works together:
Probably some work needed to ensure the unused branch does not get evaluated.
Just food for thoughts: note that type inference does the right thing when calling a function. Would a less flexible syntax work for you? It's really a lot simpler...
Also, this is available in scalaz but they name it
fold
:我一直在研究@Jean-Philippe 的解决方案,并添加了一些内容以允许链接运算符。 (好吧,我可以保持原样并使用括号,但这有什么乐趣呢?)可能有更好的方法来做到这一点,因此欢迎提出改进建议。
我更改了运算符名称:Ternary 类中的运算符需要具有较低优先级,但隐式 def 中的运算符也需要具有较低优先级,并且
|
具有除字母数字之外的最低优先级。我还添加了一个重载,以便我们可以采用另一个三元子句。
因此
很酷还是什么? :) 谁需要
if / else
呢?I've been playing around with @Jean-Philippe's solution, and made a couple of additions to allow the chaining of operators. (Well I could have just left it as it is and used parentheses, but where's the fun in that?) There's probably a better way to do this, so suggestions for improvements are welcome.
I changed the operator names: the one in the Ternary class needs to be lower priority, but the one in the implicit def also needs to be low priority, and
|
has the lowest priority other than alphanumerics.Also I added an overload, so that we can take another Ternary clause.
Hence
Cool or what? :) Who needs
if / else
anyway?