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
- jsp标签小结
- 专家解释“愤怒的小鸟”如何变身间谍
- BT5 + wireshark玩wifi捕获和中间人攻击
- Hibernate HQL注入攻击入门
- 高效开源的网络扫描框架NINJA-PingU
- 对List.Sort的简单研究
- 使用Apache API监控Uber的实时数据,第3篇:使用Vert.x的实时仪表板
- 走进科学:我是如何“黑了”星级酒店的
- OpenSSL空指针引用do_ssl3_write
- 针对近期“博全球眼球的OAuth漏洞”的分析与防范建议
- 黑掉美国(英国、澳大利亚、法国等)的交通控制系统
- Android 自定义标签 ViewLayout
- Identity Service - 解析微软微服务架构eShopOnContainers(二)
- 机器学习之随机森林
- 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 数组属性和方法
- Centos7 源码安装mysql5.6
- mysql登录时报socket找不到终极解决方案
- Grafana将数据库由sqlite3改为mysql
- Python自学成才之路 带有参数的装饰器
- Grafana 将默认的元数据库 sqlite 改为 mysql
- 使用IDEA整合spring4+spring mvc+hibernate
- springmvc中@PathVariable和@RequestParam的区别
- centos7 安装mysql5.6
- bashdb安装及调试shell脚本
- linux awk指令详解
- linux sed指令详解
- Grafana使用zabbix自定义模板
- linux shell之变量的使用规则
- 第11期:压缩表
- grafana-zabbix插件安装和配置zabbix mysql