加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 三元运算符打字

发布时间:2020-12-16 19:05:22 所属栏目:安全 来源:网络整理
导读:我实现了一个三元运算符,如 Java的 condition ? if true : if false代替/ for:,因为:不是有效的标识符: case class Ternary[T](val o: Option[T]) { def / (f: = T) = o getOrElse f}implicit def boolToTernary(cond: Boolean) = new { def ? [T](f: =
我实现了一个三元运算符,如 Java的< condition> ? < if true> :< if false>代替/ for:,因为:不是有效的标识符:

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?我搜索类似的解决方案,我发现所有的实现都表现出相同的行为.

解决方法

你可以做的一件事是改变你对/的定义:

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

它不像常规的(如果推断的类型是Double) – 您获得AnyVal,但这已经是一个改进,对您的代码进行了很小的修改.

更新:我认为我发现了一种(稍微复杂一点)的方式,使它的行为更像一个正常的(如在这种情况下,推断一个双).尝试这段代码:

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,That](val toThat1: T => That,val toThat2: U => That)

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

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

然后(一些示例代码):

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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读