scala类型系统之: 类型变量界定、视图界定、上下文界定

类型变量界定(Type Variable Bound)、视图界定(View Bound)、上下文界定(Context Bound),在scala中算很重要的内容了,这次博客就来写点自己的理解。

 

1、类型变量界定(Type Variable Bound):

  1. // 编译错误  
  2. def typeVariable[T](a: T, b: T) = {  
  3.     if (a.compareTo(b) > 0) 1  
  4.     else -1  
  5. }  
  6.   
  7. // 通过编译  
  8. def typeVariable[T <: Comparable[T]](a: T, b: T) = {  
  9.     if (a.compareTo(b) > 0) 1  
  10.     else -1  
  11. }  

在上面的例子中,我们为范型T增加了约束,限定上界为Comparable[T],这样一来,范型类型T也就具有了Comparable[T]中的compareTo(T)方法,类似于java中的继承。

 

2、视图界定(View Bound):

  1. def typeVariable[T <: Comparable[T]](a: T, b: T) = {  
  2.     if (a.compareTo(b) > 0) 1  
  3.     else -1  
  4. }  

这是我们刚刚通过编译的代码,接着我们运行一下:

  1. val v1 = typeVariable("scala", "java")  
  2. println(v1) // scala  

运行结果为:scala,但是,如果我们输入数字的话,便会报错:

  1. val v2 = typeVariable(100, 200)  
  2. println(v2)  
  3. Error:(15, 12) inferred type arguments [Int] do not conform to method typeVariable's type parameter bounds [T <: Comparable[T]]  
  4.   val v2 = typeVariable(100, 200)  
  5.            ^  

因为我们的Int类型并没有遵循我们的范型约束。如果我们此时想成功运行的话,就需要进行一次隐式转换,将Int类型转换成支持Comparable[T]的类型,那么,我们的视图界定便能出场了:

  1. def typeVariable[T <% Comparable[T]](a: T, b: T) = {  
  2.     if (a.compareTo(b) > 0) a  
  3.     else b  
  4. }  
  5. val v2 = typeVariable(100, 200)  
  6. println(v2) // 200  

从代码中发现,范型限定时,我们将"<:"改为了"<%",这样,原本的类型变量界定就转换成了视图界定,而视图界定帮我们进行了隐式转换,将Int转换成了支持Comparable[T]的RichInt类型。

 

编写代码时,"<%"的限定较为宽松,不仅继承了Comparable[T]的类能够顺利运行,而且通过隐式转换而来的继承Comparable[T]的类也能够顺利运行

 

3、上界(Upper Bound)、下界(Lower Bound):

有上界,那么也有下界,上界我们用"<:"来表示,例如:A <: B,表示B为A的上界,在java中即A继承B。

下界用">:"来表示,例如A >: B,表示B为A的下界,此时B继承A。

 

 

4、上下文界定(Context Bound):

上下文界定的类型参数形式为T:M的形式,其中M是一个泛型类,这种形式要求存在一个M[T]类型的隐式值:

  1. class Person(val age: Int) {  
  2.     println("person==> " + age)  
  3. }  
  4.   
  5. // PersonOrdering继承了Ordering[T],而Ordering[T]又继承了Comporator[T],所以下面方法中有compare(x: T, y: T)方法  
  6. class PersonOrdering extends Ordering[Person] {  
  7.   override def compare(x: Person, y: Person): Int = {  
  8.     if (x.age > y.age) 1 else -1  
  9.   }  
  10. }  
  11.   
  12. // 该类定义了一个上下文界定,意思是  
  13. // 在其作用域内,必须有一个Ordering[T]的隐式值,而这个隐式值可以作用于内部的方法  
  14. class Pair[T: Ordering](val first: T, val second: T) {  
  15.   // 该方法需要一个类型为Ordering[T]的隐式参数  
  16.   def old(implicit ord: Ordering[T]) = {  
  17.     if (ord.compare(first, second) > 0) first else second  
  18.   }  
  19. }  
  20.   
  21. // 定义一个隐式值,类型为Ordering[T]  
  22. implicit val po = new PersonOrdering  
  23. val p = new Pair(new Person(18), new Person(19))  
  24. // 调用old方法时,不需要传入参数,根据我们的上下文界定要求,po满足要求,因此作为参数传入old  
  25. println(p.old.age) // 19  

 

 

这次的博客虽然是说界定,但是也扯到了不少的隐式转换,所以需要对scala有一些基本的了解,另外文章中如果有出错的地方,欢迎指正。

原文地址: http://zk-chs.iteye.com/blog/2292468

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值