Swift 泛型
泛型解决的问题
下面的 swapTwoInts(::) 是一个标准的非泛型函数,用于交换两个 Int 值:
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
这个函数用输入输出形式参数来交换 a 和 b 的值。
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now (someInt), and anotherInt is now (anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"
swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两个 Double 值,你只能再写更多的函数,比如下面的 swapTwoStrings(::) 和 swapTwoDoubles(::) 函数:
func swapTwoStrings(_ a: inout String, _ b: inout String) {
let temporaryA = a
a = b
b = temporaryA
}
func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
let temporaryA = a
a = b
b = temporaryA
}
你可能已经注意到了, swapTwoInts(::) 、 swapTwoStrings(::) 、 swapTwoDoubles(::) 函数体是一样的。唯一的区别是它们接收值类型不同( Int 、 String 和 Double )。
泛型函数
泛型函数可以用于任何类型。这里是上面提到的 swapTwoInts(::) 函数的泛型版本,叫做 swapTwoValues(::) :
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
swapTwoValues(::) 和 swapTwoInts(::) 函数体是一样的。但是, swapTwoValues(::) 和 swapTwoInts(::) 的第一行有点不一样。下面是首行的对比:
func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)
泛型版本的函数用了一个占位符类型名(这里叫做 T ),而不是一个实际的类型名(比如 Int 、 String 或 Double )。占位符类型名没有声明 T 必须是什么样的,但是它确实说了 a 和 b 必须都是同一个类型 T ,或者说都是 T 所表示的类型。替代 T 实际使用的类型将在每次调用 swapTwoValues(::) 函数时决定。
其他的区别是泛型函数名( swapTwoValues(::) )后面有包在尖括号( <T> )里的占位符类型名( T )。尖括号告诉Swift, T 是一个 swapTwoValues(::) 函数定义里的占位符类型名。因为 T 是一个占位符,Swift 不会查找真的叫 T 的类型。
现在,可以用调用 swapTwoInts 的方式来调用 swapTwoValues(::) 函数,除此之外,可以给函数传递两个任意类型的值,只要两个实参的类型一致即可。每次调用 swapTwoValues(::) ,用于 T 的类型会根据传入函数的值类型自动推断。
在下面的两个例子中, T 分别被推断为 Int 和 String :
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// someInt is now 107, and anotherInt is now 3
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString is now "world", and anotherString is now "hello"
比较两个值的最小值
func myMin<T: Comparable>(_ a:T, _ b: T) -> T {
return a < b ? a : b
}
print("Min is:", myMin(2, 21))
// Min is: 2
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- package.json文件的作用
- C语言的原子操作
- 【Linux】tmux命令使用教程
- 【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】七、Android FFmpeg 视频编码
- 2020已经过去五分之四了,你确定还不来了解一下JS的rAF?
- c#任意进制转换
- 缺失值的处理方法(基于sklearn)
- 中国核酸数据库GSA数据提交指南
- 基于sklearn建立机器学习的pipeline
- Sentinle集群流控【源码笔记】
- ggplot坐标轴方向设置
- Scaling与Normalization的区别
- Android 音乐APP(一)扫描本地音乐
- Semaphore:如何快速实现一个限流器?
- 延迟初始化Spring Bean:延迟初始化的Bean会影响依赖注入吗?