详解 Scala 的泛型

一、协变与逆变

1. 说明

  • 协变:Son 是 Father 的子类,则 MyList[Son] 也作为 MyList[Father] 的 “子类”
  • 逆变:Son 是 Father 的子类,则 MyList[Son] 作为 MyList[Father] 的 “父类”
  • 不变:Son 是 Father 的子类,则 MyList[Father] 与 MyList[Son] 之间 “无父子关系“

2. 语法

// 不变
class MyList[T]{}

// 协变
// class MyList[+T]{}

// 逆变
// class MyList[-T]{}

class Parent{}
class Child extends Parent{}
class SubChild extends Child{}

object TestGenerics {
    def main(args: Array[String]): Unit = {
        // 不变
        var mylist1: MyList[Child] = new MyList[Child]
        // var mylist2: MyList[Parent] = new MyList[Child] // error,无父子关系
        
        // 协变
        // var mylist1: MyList[Child] = new MyList[Child]
        // var mylist2: MyList[Parent] = new MyList[Child]
        // var mylist3: MyList[Child] = new MyList[SubChild]
        
        // 逆变
        // var mylist1: MyList[Child] = new MyList[Child]
        // var mylist2: MyList[Child] = new MyList[SubChild] // error, 父子关系逆转
        // var mylist3: MyList[SubChild] = new MyList[Child]
        
    }
}

二、泛型上下限

泛型的上下限的作用是对传入的泛型进行限定

/**
	[T <: Class]:泛型上限,类型 T 只能是 Class 或 Class 子类
	[T >: Class]:泛型下限,类型 T 只能是 Class 或 Class 父类
*/
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}

object TestGenerics {
    def main(args: Array[String]): Unit = {
        def test[A <: Child](a: A) { // 类型只能是 Child及其子类
            println(a.getClass.getName)
        }
        
        test[Child](new Child)
        test[Child](new SubChild)
        test[SubChild](new SubChild)
        // test[Parent](new Child) // error
        
    }
}

三、上下文限定

1. 说明

​ 上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定 [A : Ordering] 之后,方法内无法使用隐式参数名调用隐式参数,需要通过 implicitly[Ordering[A]] 获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误

2. 语法

/**
	def f[A: B](a: A) = println(a) 
	//等同于 
	def f[A](a: A)(implicit arg: B[A]) = println(a)
*/
object TestGenerics {
    def main(args: Array[String]): Unit = {
        
        def f[A: Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
        
		def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)
    }
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>