发布时间:2022-10-26 文章分类:编程知识 投稿人:赵颖 字号: 默认 | | 超大 打印

泛型

泛型定义

Scala的泛型和Java中的泛型表达的含义都是一样的,对处理的数据类型进行约束,但是Scala提供了更加强大的功能

泛型语法

如果能将类型和泛型当成一个整体来使用的话,那不就方便了吗?

val message1 : Message[Child] = new Message[Child]()
val message2 : Message[Child] = new Message[Parent]()
//val message3 : Message[Child] = new Message[SubChild]()  -- 不符合新的父子关系
// Child(父) -> child -> SubChild(子)
// MessageChild(子)         MessageSubChild(父)
// Child(子)             Parent(父)
// MessageChild(父)      MessageParent(子)
class Message[-T] {}
class Parent {}
class Child extends Parent {}
class SubChild extends Child {}

泛型和类型的区别

泛型特征

泛型的上限与下限

Scala的泛型可以根据功能设定类树的边界

这里的上限和下限采用的是颜文字

    def main(args: Array[String]): Unit = {
        val p = new Producer[Child]
        p.produce(new Message[Child])
        p.produce(new Message[Parent])
        p.produce(new Message[SubChild]) // --> error
        val c = new Consumer[Child]
        val m: Message[_ <: Child] = c.consume()
        val data: Child = m.data
    }
    class Message[T] {
        var data : T = _
    }
    class Parent {}
    class Child extends Parent {}
    class SubChild extends Child {}
// 设置上限与下限
    class Producer[T] {
        def produce( message : Message[_ >: T] ): Unit = {
        }
    }
    class Consumer[T] {
        def consume(): Message[_ <: T] = {
            null
        }
    }

集合的泛型

使用时需甄别源码 看是否有上限下限

def main(args: Array[String]): Unit = {
        val list : List[Child] = List(
            new Child(), new Child(), new Child()
        )
    // 集合中函数要遵守继承
    	list.fold[Parent](new Parent)(
            (x,y) => x
        )
    // 但left不需要考虑继承
        list.foldLeft[SubChild](new SubChild)((x, y) => x)
    }
class Parent {}
class Child extends Parent {}
class SubChild extends Child {}

上下文限定

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

object ScalaGeneric {
    def main(args: Array[String]): Unit = {
        def f[A : Test](a: A) = println(a)
        implicit val test : Test[User] = new Test[User]
        f( new User() )
    }
    class Test[T] {
    }
    class Parent {
    }
    class User extends Parent{
    }
    class SubUser extends User {
    }
}