Young's blog Young's blog
首页
Spring
  • 前端文章1

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Young

首页
Spring
  • 前端文章1

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Hadoop

  • kafka

  • Flume

  • hive

  • scala

    • Scala 入 门
    • scala 函数式编程
    • scala 面向对象
    • scala 集合
    • scala 第 8 章 模式匹配
    • scala 第 9 章 异 常
    • 进阶

    • scala 第 11 章 泛 型
      • 11.1 协变和逆变
      • 11.2 泛型上下限
      • 11.3 上下文限定
    • scala 第 12 章 总结
  • spark

  • 大数据
  • scala
andanyang
2023-11-03
目录

scala 第 11 章 泛 型

# 第 11 章 泛 型

Java 中使用 <> 符号来包含定义的类型参数,Scala 则使用 []。

class Pair[T, S](val first: T, val second: S) {
  override def toString: String = first + ":" + second
}

object ScalaApp extends App {

  // 使用时候你直接指定参数类型,也可以不指定,由程序自动推断
  val pair01 = new Pair("heibai01", 22)
  val pair02 = new Pair[String,Int]("heibai02", 33)

  println(pair01)
  println(pair02)
}
1
2
3
4
5
6
7
8
9
10
11
12
13

函数和方法也支持类型参数。

object Utils {
  def getHalf[T](a: Array[T]): Int = a.length / 2
}
1
2
3

# 11.1 协变和逆变

1)语法

class MyList[+T]{ //协变
}
class MyList[-T]{ //逆变
}
class MyList[T] //不变
1
2
3
4
5

2)说明

  • 协变:Son 是 Father 的子类,则 MyList[Son] 也作为 MyList[Father]的“子类”。

  • 逆变:Son 是 Father 的子类,则 MyList[Son]作为 MyList[Father]的“父类”。

  • 不变:Son 是 Father 的子类,则 MyList[Father]与 MyList[Son]“无父子关系”。

3)实操

//泛型模板
//class MyList<T>{}
//不变
//class MyList[T]{}
//协变
//class MyList[+T]{}
//逆变
//class MyList[-T]{}

class Parent{}

class Child extends Parent{} 

class SubChild extends Child{}

object Scala_TestGeneric {
    def main(args: Array[String]): Unit = {
    //var s:MyList[Child] = new MyList[SubChild]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 11.2 泛型上下限

Scala 和 Java 一样,对于对象之间进行大小比较,要求被比较的对象实现 java.lang.Comparable 接口。所以如果想对泛型进行比较,需要限定类型上界为 java.lang.Comparable,语法为 S <: T,代表类型 S 是类型 T 的子类或其本身。示例如下:

1) 语法

Class PersonList[T <: Person]{ //泛型上限

}

Class PersonList[T >: Person]{ //泛型下限

}

2)说明

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

3)实操

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

object Scala_TestGeneric {
    def main(args: Array[String]): Unit = {

    //test(classOf[SubChild])
    //test[Child](new SubChild)
    }

    //泛型通配符之上限
    //def test[A <: Child](a:Class[A]): Unit ={
    //	println(a)
    //}

    //泛型通配符之下限
    //def test[A >: Child](a:Class[A]): Unit ={
    //	println(a)
    //}

    //泛型通配符之下限 形式扩展
    def test[A >: Child](a:A): Unit ={ 
    	println(a.getClass.getName)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 11.3 上下文限定

1)语法 def f[A : B](a: A) = println(a) //等同于 def f[A](a:A)(implicit arg:B[A])=println(a)

2)说明

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

implicit val x = 1
val y = implicitly[Int]
val z = implicitly[Double]
1
2
3

3)实操

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)
1
2
编辑 (opens new window)
上次更新: 2024/04/19, 08:52:45
scala eq,equals,==,===
scala 第 12 章 总结

← scala eq,equals,==,=== scala 第 12 章 总结→

最近更新
01
idea 热部署插件 JRebel 安装及破解,不生效问题解决
04-10
02
spark中代码的执行位置(Driver or Executer)
12-12
03
大数据技术之 SparkStreaming
12-12
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Young | MIT License
浙ICP备20002744号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式