Scala 类型参数的界定

<: - 上界

trait Similar {
  def isSimilar(x: Any): Boolean
}
case class MyInt(x: Int) extends Similar {
  def isSimilar(m: Any): Boolean =
    m.isInstanceOf[MyInt] &&
    m.asInstanceOf[MyInt].x == x
}
object UpperBoundTest extends App {
  def findSimilar[T <: Similar](e: T, xs: List[T]): Boolean =
    if (xs.isEmpty) false
    else if (e.isSimilar(xs.head)) true
    else findSimilar[T](e, xs.tail)
  val list: List[MyInt] = List(MyInt(1), MyInt(2), MyInt(3))
  println(findSimilar[MyInt](MyInt(4), list))
  println(findSimilar[MyInt](MyInt(2), list))
}

>: - 下界

case class ListNode[+T](h: T, t: ListNode[T]) {
  def head: T = h
  def tail: ListNode[T] = t
  def prepend[U >: T](elem: U): ListNode[U] =
    ListNode(elem, this)
}
object LowerBoundTest extends App {
  val empty: ListNode[Null] = ListNode(null, null)
  val strList: ListNode[String] = empty.prepend("hello")
                                       .prepend("world")
  val anyList: ListNode[Any] = strList.prepend(12345)
}

<% - 视图界定(view bound)

视图定界是Scala引入的一种机制:它能确保类型A的使用就像类型B一样,基本语法如下:
def f[A <% B](a: A) = a.bMethod
换句话说,A能够隐式转换为B,所以A的对象能够调用B的方法。在Scala标准库(Scala 2.8.0以前)中视图定界通常是和Ordered连用,如:
def f[A <% Ordered[A]](a: A, b: A) = if (a < b) a else b
因为A能够转换为Order[A],Ordered[A]又定义了方法<(other: A): Boolean,所以可以使用表达式a<b。不过视图定界已经过期了,尽量避免使用。

: - 上下文界定(context bound)

上下文界定是Scala 2.8.0引入的,它描述的是隐式值,而非视图定界的隐式转换,用来声明某种类型A,那么就存在隐式类型B[A],基本语法如下:
def f[A : B](a: A) = g(a) // g需要类型为B[A]的隐式值
常用用法:

def f[A : ClassManifest](n: Int) = new Array[A](n)

def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)

def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b

def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b)


参考资料

1、Scala中的协变,逆变,上界,下界等

2、scala雾中风景(10): 逆变点与协变点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值