三元运算符输入 [英] Ternary operator typing

查看:127
本文介绍了三元运算符输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了Java的< condition>之类的三元运算符。 ? <如果为true> :< if false> ,用 / 替换,因为不是有效的标识符:

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
                     ^

我可以对类型进行任何调整吗使它像内置的 if(1> 2)5 else 6.0 一样工作吗?我在Google上搜索了类似的解决方案,并发现所有实现都表现出相同的行为。

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.

推荐答案

您可以做的一件事就是更改定义 / 的对此:

One thing you can do is change your definition of / to this:

def /[U >: T](f: => U) = o getOrElse f

if (推断的类型为 Double )—您将获得 AnyVal ,但这已经是对代码的非常小的修改。

It doesn't work like a regular if (where the inferred type would be Double) — you get AnyVal, but that's already an improvement with a very small modification to your code.

更新:我想我已经找到了(稍微复杂一些的方法),使其表现得更像正常的if(例如,在这种情况下,推断 Double )。尝试以下代码:

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:

implicit def boolToTernary(cond: Boolean) = new {
  def ?[T](f: => T) = if (cond) Ternary(Some(f))
  else Ternary[T](None)
}

case class Ternary[T](val o: Option[T]) {
  def /[U, That](f: => U)(implicit conv: BiConverter[T, U, That]): That = o map conv.toThat1 getOrElse (conv toThat2 f)
}

class BiConverter[T, U, That](val toThat1: T => That, val toThat2: U => That)

trait LowPriorityBiConverterImplicits {
  implicit def subtype[A, T <: A, U <: A]: BiConverter[T, U, A] = new BiConverter[T, U, A](identity[T], identity[U])
}

object BiConverter extends LowPriorityBiConverterImplicits {
  implicit def identityConverter[T]: BiConverter[T, T, T] = new BiConverter[T, T, T](identity, identity)
  implicit def firstAsSecond[T, U](implicit conv: T => U): BiConverter[T, U, U] = new BiConverter[T, U, U](conv, identity)
  implicit def secondAsFirst[T, U](implicit conv: U => T): BiConverter[T, U, T] = new BiConverter[T, U, T](identity, conv)
}

然后(一些示例代码):

Then (some sample code):

abstract class Fruit
class Apple extends Fruit
class Banana extends Fruit

def main(args: Array[String]) {
  val int = (1 > 2) ? 5 / 6 // Int is inferred
  val fruit = (1 > 2) ? new Apple / new Banana // Fruit is inferred
  val double1 = (1 > 2) ? 5 / 5.5 // Double is inferred
  val double2 = (1 > 2) ? 5.5 / 5 // Double is inferred
}

这篇关于三元运算符输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆