swift 泛型

Swift ——泛型与集合 下面的 multiNumInt 是个非泛型函数,主要用于计算两个数的乘积 multiNum 函数很实用,但是它只能用于 Int 值。如果我们想计算两个 Double 或者 其他类型的乘积的值,我们需要在写一些函数,比如 multiNumDouble函数: 但是我们发现, 函数体是一样的。唯一的区别是它 们接收值类型不同( Int和double)。这个时候我们想找到一个可以计算任意类型值的函数怎么办?泛型正是能让我们写出这样函数的语法。我们先来看一下泛型的基本写法 ,首先我我们要指定一个占位符 T ,紧挨着写 阅读详情

泛型函数

泛型函数可以适用于任何类型:
func swapTwoValues<T>(_ a: inout T, _ b: inout T) { let temporaryA = a
a= b
b = temporaryA
}
func swapTwoInts(_ a: inout Int, _ b: inout Int)
func swapTwoValues<T>(_ a: inout T, _ b: inout T)
这个函数的泛型版本使用了占位类型名来代替实际类型名。占位类型名没有指明T必须是什么类型,但是它指明了a和b必须是同一类型T,无论T代表什么类型,只有swapTwoValues(_:_:)函数在调用时,才能根据传入的实际类型决定T所代表的类型。
另外一个不同之处在于这个泛型函数名后面跟着占位类型名,并用尖括号括起来。这个尖括号告诉swift那个T是swapTwoValues(_:_:)函数定义内的一个占位类型名,因此swift不会去查找名为T的实际类型。
var someInt = 3
var anotherInt = 107 swapTwoValues(&someInt, &anotherInt)
// someInt 现在 107, and anotherInt 现在 3
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// someString 现在 "world", and anotherString 现在 "hello"

泛型类型

除了泛型函数,swift还允许你定义泛型。这些自定义类、结构体和枚举可以适用于任何类型,类似于Array和Dicitionary。
这部分内容将向你展示如果编写一个名为Stack的泛型集合类型。栈是一系列值的有序集合,和Array类似,但它相比swift的Array类型有更多的操作限制。数组允许在数组的任意位置插入元素或是删除其中任意位置的元素。而栈只允许在集合的末端添加新的元素。
 struct Stack<Element> {
     var items = [Element]()
     mutating func push(item: Element) {
         items.append(item)
     }
     mutating func pop() -> Element {
         return items.removeLast()
} }
这些方法被标记为mutating,因为它们需要修改结构体的Item数组。

扩展一个泛型类型

当你扩展一个泛型类型的时候,并不需要再扩展的定义中提供类型参数列表。原始类型定义汇总声明的类型参数列表在扩展中可以直接使用,并且这些来自原始类型中的参数名称会被用作原始定义中类型参数的引用。
 extension Stack {
     var topItem: Element? {
         return items.isEmpty ? nil : items[items.count - 1]
     }
}
计算型属性现在可以用来访问任意Stack实例的顶端元素且不移除它:
 if let topItem = stackOfStrings.topItem {
     print("The top item on the stack is \(topItem).")
}

类型约束

下面的函数为非泛型函数,该函数的功能是在一个String数组中查找给定String值的索引。
 func findIndex(ofString valueToFind: String, in array: [String]) -> Int? {
     for (index, value) in array.enumerated() {
         if value == valueToFind {
             return index
} }
return nil }
 let strings = ["cat", "dog", "llama", "parakeet", "terrapin"]
 if let foundIndex = findIndex(ofString: "llama", in: strings) {
     print("The index of llama is \(foundIndex)")
 }
下面展示的上述的函数的泛型版本
 func findIndex<T>(of valueToFind: T, in array:[T]) -> Int? {
     for (index, value) in array.enumerated() {
         if value == valueToFind {
             return index
} }
return nil }
上面所写的函数无法通过编译。问题出在相等性检查上,不是所有的swift类型都可以用等式符进行比较。不过,所有的这些并不会让我们无从下手。swift标准库中定义了一个Equatable协议,该协议要求任何遵循该协议的类型必须实现等式符及不等符,从而能对该类型的任何两个值进行比较。所有的swift标准类型自动支持Equatable协议。
 func findIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int? {
     for (index, value) in array.enumerate() {
         if value == valueToFind {
             return index
} }
return nil }
任何符合Equatable协议的类型T都能用这个泛型函数:
let doubleIndex = findIndex(of: 9.3, in: [3.14159, 0.1, 0.25])
// doubleIndex 类型为 Int?,其值为 nil,因为 9.3 不在数组中
let stringIndex = findIndex(of: "Andrea", in: ["Mike", "Malcolm", "Andrea"]) // stringIndex 类型为 Int?,其值为 2

关联类型

下面例子定义了一个Container协议,该协议定义了一个关联类型:
protocol Container {
    associatedtype ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}
由于swift的类型推断,实际上不用再Stack的定义中声明ItemType为Int。因为Stack符合Container协议的所有要求,swift只需通过append(_:)方法的item参数类型和下标返回值的类型,就可以推断出ItemType的具体类型。实际上,如果在不写typealias ItemType = Int 这一行,一切仍旧可以正常工作,因为swift清楚的知道ItemType应该是那种类型:
struct Stack<Element>: Container {
// Stack<Element> 的原始实现部分 var items = [Element]()
mutating func push(item: Element) {
         items.append(item)
     }
     mutating func pop() -> Element {
         return items.removeLast()
}
// Container 协议的实现部分
mutating func append(item: Element) {
         self.push(item)
     }
     var count: Int {
         return items.count
     }
     subscript(i: Int) -> Element {
         return items[i]
     }
}

泛型Where语句

为关联类型定义约束也是非常有用的。可以在参数列表中通过where子句为关联类型定义约束。能通过where子句要求一个关联类型遵从某个特定的协议,以及某个特定的类型参数和关联类型必须类型相同。可以通过将where关键字跟在类型参数列表后面来定义where子句,where子句后跟一个或者多个针对关联类型的约束,以及一个或多个类型参数和关联类型间的相等关系。可以在函数体或者类型的大括号之前添加where子句。
func allItemsMatch<C1: Container, C2: Container>
    (_ someContainer: C1, _ anotherContainer: C2) -> Bool
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable {
// 检查两个容器含有相同数量的元素
if someContainer.count != anotherContainer.count {
            return false
        }
// 检查每一对元素是否相等
for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
} }
// 所有元素都匹配,返回 true return true
}
这个函数接受两个参数,参数someContainer的类型为C1,参数anotherContainer的类型为C2。C1和C2是容器的两个占位类型参数,函数被调用时才能确定他们的具体类型。
这个函数的类型参数列表还定义了对两个类型参数的要求:
C1必须符合Container协议
C2必须符合Container协议
C1的ItemType必须和C2的ItemType类型相同
C1的ItemType必须符合Equatable协议
 var stackOfStrings = Stack<String>()
 stackOfStrings.push("uno")
 stackOfStrings.push("dos")
 stackOfStrings.push("tres")
 var arrayOfStrings = ["uno", "dos", "tres"]
 if allItemsMatch(stackOfStrings, arrayOfStrings) {
     print("All items match.")
 } else {
     print("Not all items match.")
}
// 打印 “All items match.”

取自《the swift programming language》中文版
FAST-LIO 实战:从 LI-Init 标定到 YAML 配置全解析 本文详细解析了FAST-LIO算法中LI-Init标定的关键步骤与YAML配置优化技巧。从激光雷达与IMU的时空标定原理到实战参数调优,提供了一套完整的解决方案,帮助开发者解决点云畸变、建图漂移等常见问题,提升SLAM系统在动态环境中的稳定性和精度。 阅读详情

相关推荐

Vue3结合vue-office实现Word文档上传与预览全流程解析

本文详细解析了如何在Vue3项目中集成vue-office插件实现Word文档上传与预览功能。从项目初始化、插件安装到文件上传处理(包括ArrayBuffer转换)、预览优化及常见问题解决方案,提供了一套完整的实现流程,帮助开发者快速实现高效的文档预览功能。

weixin_29001327的博客 464

Swift 泛型详解

泛型在开发中的使用场景主要在以下几方面: 泛型函数 泛型类 泛型约束 泛型下标 A. 泛型函数 泛型函数指的是:函数的参数或返回值类型使用泛型,而不是具体的类型 泛型函数的格式: func 函数名<泛型1, 泛型2, …>(形参1, 形参2, ...) -> 返回类型 { 函数体 } 需求:实现Swift高阶函数reduce功能的一个函数 func myReduce<T, U>(arr: [T], initialValue: U, partialResult:

Rey的技术博客 5884

MTK Linux Charger驱动分析(二) - power_supply_core.c

的核心作用可以概括为:提供统一的电源管理框架;管理电源设备注册、属性访问、事件通知;封装sysfs 接口和 uevent 通知,屏蔽硬件细节;驱动开发者只需要实现,不关心底层通知和接口细节。简单来说,它是电源子系统的“大脑和中枢”,具体的电池/充电器只是“信息源”。

iTom1900 1488

11、Swift中的泛型

12、Swift中的泛型1、泛型函数1.1 泛型函数基础1.2 带有类型约束的泛型函数2、泛型类型3、泛型扩展 1、泛型函数 1.1 泛型函数基础 func swapTwoValues<T>(a:inout T,b:inout T){ (b,a) = (a,b) } var a:Double = 10 var b:Double = 11 swapTwoValues(a: &a, b: &b) print(a) print(b) 这个尖括号告诉Swift那个T是swap

重楼的博客 1325

浮点数运算的陷阱与启示:FP16加法器/乘法器开发中的常见误区

本文深入探讨FP16加法器和乘法器开发中的常见误区,包括FP16格式解析、阶码对齐陷阱、尾数运算风险及规格化处理。通过Verilog实战代码展示防御性编程技巧,帮助开发者避免边界条件处理和异常状态管理中的错误,提升硬件设计的可靠性和效率。

dell8的博客 249

普冉PY32F002B ADC内部参考电压VREFINT的误差补偿与低功耗优化实践

本文详细介绍了普冉PY32F002B单片机在锂电池供电场景下ADC内部参考电压VREFINT的误差补偿与低功耗优化实践。通过分析GPIO配置、分压电阻匹配、采样时间设置等硬件设计要点,结合实时测量VREFINT电压值和软件补偿算法,有效提升了ADC测量精度至5mV以内,并实现了分压电路功耗控制与采样频率优化,为低成本消费电子项目提供了完整的解决方案。

845

swift学习:泛型

  泛型代码让你能够根据自定义的需求,编写出适用于任意类型、灵活可重用的函数及类型。它能让你避免代码的重复,用一种清晰和抽象的方式来表达代码的意图。   泛型是 swift 最强大的特性之一,许多swift 标准库是通过泛型代码构建的。事实上,泛型的使用贯穿了整本语言手册,只是你可能没有发现而已。例如,swift 的 Array 和 Dictionary 都是泛型集合。你可以创建一个Int 数组...

weixin_30619101的博客 162

《UDS协议从入门到精通》系列——到底什么是DTC?

到底什么是DTC?看这里,深度图解DTC格式,详述DTC状态位、快照信息和扩展信息!!

车载系统攻城狮 1万+

Swift高级特性之泛型

本章你会了解Swift高级特性中的泛型的使用

王偃飞的博客 902

Codex 接入自定义大模型终极教程:插件解锁、会话管理、国产模型一键搞定

🚀 Codex 默认只能使用 OpenAI 官方模型?这篇文章带你从零接入 DeepSeek、通义千问、GLM 等国产大模型,并彻底解锁插件、会话删除、多模型切换等隐藏功能。配置原理、常见坑点、傻瓜式增强工具分享,小白也能轻松上手!🔥

XiaoqiangClub的博客 3142

使用亚组分析进行子组分析并可视化森林图 - R语言

通过亚组分析和森林图的结合,我们可以更好地理解不同子组之间的差异和效果大小。当然,在实际应用中,还需要考虑多种因素,如样本量、异质性等,以得到更准确的结果和结论。每个森林图中的水平线代表了每个子组的效应估计,线的长度表示了该效应估计的置信区间。假设我们有一个包含研究对象的数据框(data frame),其中包括了治疗组和对照组的结果数据,以及一些可能的影响因素作为调整变量。在本例中,我们将比较两种不同的治疗方法(A和B)对结果变量的影响,并调整了一个额外的变量。是结果变量和对照组变量的列名。

2301_79326857的博客 1234

swift中的泛型

swift的泛型

JH_Cao的博客 526

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Swift 泛型

泛型代码让你能根据自定义的需求,编写出适用于任意类型的、灵活可复用的函数及类型。你可避免编写重复的代码,而是用一种清晰抽象的方式来表达代码的意图。泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的。实际上,即使你没有意识到,你也一直在语言指南中使用泛型。例如,Swift 的Array和Dictionary都是泛型集合。你可以创建一个Int类型数组,也可创建一个String类型数组,甚至可以是任意其他 Swift 类型的数组。

xiaoxiaobukuang的专栏 1564

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Swift里泛型

泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的。实际上,即使你没有意识到,你也一直在语言指南中使用泛型。例如,Swift 的Array和Dictionary都是泛型集合。你可以创建一个Int类型数组,也可创建一个String类型数组,甚至可以是任意其他 Swift 类型的数组。 泛型解决的问题(不同类型数据进行相同运算的问题?) // Int 类型的值交换函数 func swapTwoInts(_ a: inout Int, _ b: inout I...

1046

swift泛型

泛型代码可以确保你写出灵活的,可重用的函数和定义出任何你所确定好的需求的类型。你的可以写出避免重复的代码,并且用一种清晰的,抽象的方式表达出来。 泛型是Swift需要强大特征中的其中一个,许多Swift标准库是通过泛型代码构建出来的。事实上,你已经使用泛型贯穿着整个Language Guide,即便你没有实现它。例如:Swift的Array和Dictionary类型都是泛型集。你可以创建一个

leihua713的专栏 948

如何在Swift中使用泛型

泛型允许您声明一个变量,该变量在执行时可以分配给我们定义的一组类型。 在Swift中,数组可以保存任何类型的数据。 如果需要整数,字符串或浮点数的数组,则可以使用Swift标准库创建一个数组。 声明数组时应定义的类型。 数组是使用泛型的常见示例。 如果要实现自己的集合,则肯定要使用泛型。 让我们探究泛型及其允许我们做的伟大的事情。 1.通用功能 我们首先创建一个简单的泛型函数。...

代码教主 2360

Swift - 泛型

泛型是Swift中重要的类型之一,意为不确定的类型。我们知道带有参数的函数是必需要指定参数的类型的,举个例子观察下面有几个同名函数实现相似的功能,但参数类型不同: 一、节点泛型 func methodOne(param:String) { print("\(param)") } func methodTwo(param:Int) { prin...

SSY_1992的博客 585

Swift学习之泛型

文章目录简介泛型函数泛型类型泛型扩展 简介 泛型可以使我们在程序代码中定义一些可变的部分,在运行的时候指定。使用泛型可以最大限度地重用代码,保护类型安全以及提高性能。在Swift集合中数组、Set和字典都是泛型集合。 泛型函数 func isEquals&lt;T:Comparable&gt;(a:T,b:T)-&gt;Bool{ return (a==b) } let a = 10 ...

面壁者LOGIC 436

[Swift]泛型

1. Swift泛型的定义方法:     1) 和C++泛型概念一样,用法和C++也相似,同样也是使用一个类型占位符(代表一个通用类型,也是泛型的参数,用户随意取名,但要求按照标示符命名规则进行,因为其代表一个通用类型,因此和定义其它类型名的规范一样,最好是首字母大写的驼峰命名方式,一般取T);     2) 一个简单的泛型函数的例子: func mySwap(inout a: T, ino

Lirx_Tech的专栏 1350

Swift泛型

泛型是为Swift编程灵活性的一种语法,在函数、枚举、结构体、类中都得到充分的应用,它的引入可以起到占位符的作用,当类型暂时不确定的,只有等到调用函数时才能确定具体类型的时候可以引入泛型。泛型函数定义fun 函数名<T,S>(形参列表)->返回值类型 { //函数体... } 例子: func copyArray<T>(src:[T],inout dest:[T]) { for e

小王的技术窝 2007
上一篇: swift 协议
下一篇: 关于 Cannot create __weak reference in file using manual reference counting及配置ReactiveCocoa
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值