仓颉开发之——泛型(10)
一 概述
- 泛型概述
- 泛型函数
- 泛型接口
- 泛型类
- 泛型结构体
- 泛型枚举
- 类型别名
- 泛型约束
二 泛型概述
2.1 什么是泛型
- 泛型指的是参数化类型,参数化类型是一个在声明时未知并且需要在使用时指定的类型
- 类型声明与函数声明可以是泛型的
- 最为常见的例子就是 Array<T>、Set<T> 等容器类型
2.1.1 几个常用术语
1 | class List<T> { |
说明:
- 类型形参:List<T> 中的 T
- 类型变元: elem: Option<T> 中对 T 的引用
- 类型实参: sumInt 的参数中 List<Int64> 的 Int64
- 类型构造器:func sumInt(a: List<Int64>)中List就是类型构造器
三 泛型函数
3.1 泛型函数概念
- 一个函数声明了一个或多个类型形参,则将其称为泛型函数
- 类型形参紧跟在函数名后,并用 <> 括起,有多个类型形参用“,”分离。
3.2 全局泛型函数
1 | func id<T>(a: T): T { |
说明:
- 在函数名后使用尖括号声明类型形参,然可以在函数形参、返回类型及函数体中对其进行引用
- 泛型函数 composition func composition<T1, T2, T3>(f: (T1) -> T2, g: (T2) -> T3): (T1) -> T3{} 声明了 3 个类型形参,分别是 T1, T2, T3,其功能是把两个函数 f: (T1) -> T2, g: (T2) -> T3 复合成类型为 (T1) -> T3 的函数。
3.3 局部泛型函数
1 | func foo(a: Int64) { |
说明:
~>
是composition 函数,是两个函数的复合- 根据推测和结果可知:函数 id<Int64> ~> double 和 double ~> id<Int64> 是等价的
3.4 泛型成员函数
1 | class A { |
说明:
- class、struct 与 enum 的成员函数可以是泛型的
- class 中声明的泛型成员函数不能被 open 修饰,如果被 open 修饰则会报错
4.4 静态泛型函数
1 | import std.collection.* |
五 泛型接口
1 | public interface Iterable<E> { |
说明:接口interface中的泛型
六 泛型类
1 | public open class Node<K, V> where K <: Hashable & Equatable<K> { |
说明:class中的泛型
七 泛型结构体
1 | struct Pair<T, U> { |
说明:struct结构体中的泛型
八 泛型枚举
1 | package core // `Option` is defined in core. |
说明:enum枚举中的泛型
九 类型别名
1 | type I64 = Int64 |
说明:
- 使用type为此类型设置一个别名
- type +别名+ = 最后是原类型
- 只能在源文件顶层定义类型别名
十 泛型约束
10.1 概念
- 约束大致分为接口约束与子类型约束
- 语法为在函数、类型的声明体之前使用 where 关键字来声明
- 同一个类型变元的多个约束可以使用 & 连接
10.2 示例
1 | func genericPrint<T>(a: T) where T <: ToString { |
十一 思维导图
十二 参考
- 仓颉官方文档—泛型
- 仓颉编程语言入门教程