美文网首页
2.类型变量界定、视图界定、上下文界定

2.类型变量界定、视图界定、上下文界定

作者: 丹之 | 来源:发表于2019-01-17 20:18 被阅读18次

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

// 编译错误  
def typeVariable[T](a: T, b: T) = {  
    if (a.compareTo(b) > 0) 1  
    else -1  
}  
  
// 通过编译  
def typeVariable[T <: Comparable[T]](a: T, b: T) = {  
    if (a.compareTo(b) > 0) 1  
    else -1  
}  

对泛型做了约束,有点类似java中的继承

2、视图界定(View Bound):

def typeVariable[T <: Comparable[T]](a: T, b: T) = {  
    if (a.compareTo(b) > 0) 1  
    else -1  
}  
val v1 = typeVariable("scala", "java")  
println(v1) // scala  

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

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

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

def typeVariable[T <% Comparable[T]](a: T, b: T) = {  
    if (a.compareTo(b) > 0) a  
    else b  
}  
val v2 = typeVariable(100, 200)  
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]类型的隐式值:

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

完整代码:

package scala.context

object Test {

  //类型变量界定(Type Variable Bound)

  //编译错误
  /*def typeVariable[T](a: T, b: T) = {
    if (a.compareTo(b) > 0) 1
    else -1
  }*/

  // 通过编译
  def typeVariable[T <: Comparable[T]](a: T, b: T) = {
    if (a.compareTo(b) > 0) 1
    else -1
  }

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

  //输入数字的话,便会报错:

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

  //进行一次隐式转换,将Int类型转换成支持Comparable[T]的类型
  //类型变量界定就转换成了视图界定
  def typeVariable1[T <% Comparable[T]](a: T, b: T) = {
    if (a.compareTo(b) > 0) a
    else b
  }
  val v2 = typeVariable(100, 200)
  println(v2) // 200


}

package scala.context

class Person(val age: Int) {
  println("person==> " + age)
}

// PersonOrdering继承了Ordering[T],而Ordering[T]又继承了Comporator[T],所以下面方法中有compare(x: T, y: T)方法
class PersonOrdering extends Ordering[Person] {
  override def compare(x: Person, y: Person): Int = {
    if (x.age > y.age) 1 else -1
  }
}

// 该类定义了一个上下文界定,意思是
// 在其作用域内,必须有一个Ordering[T]的隐式值,而这个隐式值可以作用于内部的方法
class Pair[T: Ordering](val first: T, val second: T) {
  // 该方法需要一个类型为Ordering[T]的隐式参数
  def old(implicit ord: Ordering[T]) = {
    if (ord.compare(first, second) > 0) first else second
  }
}

object ContextBoundTest {

  def main(args: Array[String]): Unit = {
    // 定义一个隐式值,类型为Ordering[T]
    implicit val po = new PersonOrdering

    val p = new Pair(new Person(18), new Person(19))
    // 调用old方法时,不需要传入参数,根据我们的上下文界定要求,po满足要求,因此作为参数传入old
    println(p.old.age) // 19
  }

}

相关文章

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

    类型变量界定(Type Variable Bound)、视图界定(View Bound)、上下文界定(Contex...

  • 2.类型变量界定、视图界定、上下文界定

    1、类型变量界定(Type Variable Bound): 对泛型做了约束,有点类似java中的继承 2、视图界...

  • 界定

    界定一只流浪的猫和流浪的狗 界定法国梧桐的叶子永不会凋落 公园的长椅将在夜晚和路灯谈话 它让虚无走出迷惘在街的尽头...

  • 界定

    关系有时候是难以界定的,尤其是感情。但当相处成为压力的时候,这个关系就得了病。作,只能让它不断恶化。谈,或许能让它...

  • 界定

    或者 只有这样 我便用不委屈自己 来一次次的委屈着 因为那些关乎血缘的 以及无关乎血缘的 是衡量你我的必要界定 距...

  • 界定

    告诉你,我只是天上流浪的那颗星 荒野上的那个孤魂 只要你望望星空 只要你定定眼神 你就会感觉到那个生存 我的真

  • 界定

    迈入成年的行列后,内向外向的界定越来越模糊,因为不管内向还是外向,该做的事都得毫无破绽的做好,该说的话也得原封不动...

  • 界定

    所谓的人世一遭, 清醒和迷糊, 正常和神经, 如何分辨, 又怎么云云个所以然? 呱呱落地, 便乖巧的或者说顺从, ...

  • 界定

    她总说最爱超大太阳,与和煦的暖风。 而他喜欢潮湿阴冷天,沙发上胡乱想。 她最爱音乐,喜欢在房间里哼哼没完。 而他最...

  • 如何界定以及谁去界定

    我的朋友,相信世界会持续健康发展下去,你的乐观我乐于见到,但知道这种可能性微乎其微,人只能适应未来的变化。 俄乌冲...

网友评论

      本文标题:2.类型变量界定、视图界定、上下文界定

      本文链接:https://www.haomeiwen.com/subject/onrwdqtx.html