当前位置: 首页 > news >正文

【IOS开发】swift的泛型使用

一、泛型的作用

类型安全:在编译时保证类型一致性
代码复用:编写可处理多种类型的通用代码
抽象能力:创建灵活且类型安全的抽象层

1. 解决代码重复问题

// 没有使用泛型
// 需要为每种类型写重复代码
func swapInts(_ a: inout Int, _ b: inout Int) {let temp = aa = bb = temp
}func swapStrings(_ a: inout String, _ b: inout String) {let temp = aa = bb = temp
}func swapDoubles(_ a: inout Double, _ b: inout Double) {let temp = aa = bb = temp
}
// 使用泛型
// 一个函数处理所有类型
func swapValues<T>(_ a: inout T, _ b: inout T) {let temp = aa = bb = temp
}// 使用示例
var a = 5, b = 10
swapValues(&a, &b)var x = "hello", y = "world"
swapValues(&x, &y)

2. 类型安全优势

// 非泛型:容易导致运行时错误
class AnyBox {var value: Anyinit(_ value: Any) { self.value = value }
}let box = AnyBox(42)
let string = box.value as? String // 需要强制转换,可能失败// 泛型:编译时类型安全
class Box<T> {var value: Tinit(_ value: T) { self.value = value }
}let intBox = Box(42)
let intValue = intBox.value // 类型明确为 Int,无需转换

二、使用

1. 基础语法

// 泛型函数
func makeArray<T>(repeating item: T, count: Int) -> [T] {return Array(repeating: item, count: count)
}// 泛型类型
struct Pair<T, U> {let first: Tlet second: U
}// 泛型协议
protocol Container {associatedtype Itemvar count: Int { get }mutating func append(_ item: Item)subscript(i: Int) -> Item { get }
}

2. 类型约束

// 基本约束
func areEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {return a == b
}// 多约束
func process<T>(_ value: T) where T: Comparable, T: CustomStringConvertible {print("Processing: \(value.description)")
}// 协议关联类型约束
protocol Identifiable {associatedtype ID: Hashablevar id: ID { get }
}struct User: Identifiable {let id: Int  // Int 符合 Hashable
}

3. 关联类型

protocol Store {associatedtype Itemassociatedtype Key: Hashablevar items: [Key: Item] { get set }func get(_ key: Key) -> Item?mutating func set(_ item: Item, for key: Key)
}// 实现协议时指定具体类型
class StringStore: Store {typealias Item = Stringtypealias Key = Stringvar items: [String: String] = [:]func get(_ key: String) -> String? {return items[key]}func set(_ item: String, for key: String) {items[key] = item}
}

三、注意事项

1. 性能考虑

// 泛型在编译时特化,没有运行时开销
struct Buffer<T> {private var elements: [T]// 对于值类型,编译器会为每种使用的 T 生成特化版本// 性能与手写特定类型代码相同
}// 但要注意:复杂的类型约束可能增加编译时间
func complexFunction<T>(_ value: T) where T: Collection,T.Element: Equatable,T.Index == Int {// 复杂的约束需要更多编译时间
}

2. 类型擦除模式

// 问题:协议带有关联类型时不能直接用作类型
// protocol Processor<T> { } // 错误写法// 解决方案:类型擦除
protocol Processor {associatedtype Inputassociatedtype Outputfunc process(_ input: Input) -> Output
}// 类型擦除包装器
struct AnyProcessor<Input, Output>: Processor {private let _process: (Input) -> Outputinit<P: Processor>(_ processor: P) where P.Input == Input, P.Output == Output {self._process = processor.process}func process(_ input: Input) -> Output {return _process(input)}
}// 使用
let processors: [AnyProcessor<String, Int>] = [] // 现在可以放入数组

3. 泛型继承

class BaseClass<T> {var value: Tinit(_ value: T) {self.value = value}
}// 子类可以继承泛型参数
class SubClass<T>: BaseClass<T> {func transform<U>(_ transformer: (T) -> U) -> U {return transformer(value)}
}// 或者固定泛型参数
class IntProcessor: BaseClass<Int> {func double() -> Int {return value * 2}
}

四、其他用法

1. 泛型扩展

extension Array where Element: Numeric {func sum() -> Element {return reduce(0, +)}
}extension Collection where Element: Equatable {func allEqual() -> Bool {guard let first = self.first else { return true }return allSatisfy { $0 == first }}
}// 使用
let numbers = [1, 2, 3, 4]
print(numbers.sum()) // 10let sameNumbers = [5, 5, 5, 5]
print(sameNumbers.allEqual()) // true

2. 不透明类型

// 使用 some 关键字返回具体但隐藏的类型
protocol Shape {func draw() -> String
}struct Square: Shape {func draw() -> String { return "□" }
}struct Circle: Shape {func draw() -> String { return "○" }
}// 返回具体类型,但对外隐藏具体实现
func makeShape() -> some Shape {return Square() // 编译时确定类型,但调用方只知道是 Shape
}// 与泛型结合
func makeShape<T: Shape>(_ type: T.Type) -> some Shape {return type.init()
}

3. 泛型下标

struct JSON {private var storage: [String: Any]// 泛型下标subscript<T>(key: String) -> T? {return storage[key] as? T}
}let json = JSON(storage: ["name": "John", "age": 30])
let name: String? = json["name"]  // 类型明确的访问
let age: Int? = json["age"]       // 自动类型推断

五、实际应用

1. 网络层泛型应用

class APIClient {func request<T: Decodable>(_ endpoint: String,method: String = "GET") async throws -> T {// 通用网络请求实现let data = try await performRequest(endpoint, method: method)return try JSONDecoder().decode(T.self, from: data)}
}// 使用
let client = APIClient()
let user: User = try await client.request("/users/1")
let posts: [Post] = try await client.request("/posts")

2. 数据持久化泛型

protocol Database {associatedtype Entity: Identifiablefunc save(_ entity: Entity)func fetch(by id: Entity.ID) -> Entity?func delete(_ entity: Entity)
}class CoreDataDatabase<Entity: Identifiable & NSManagedObject>: Database {// 具体实现...
}
http://www.dtcms.com/a/571047.html

相关文章:

  • 网站建设结单 优帮云免费建造网站
  • 网站销售优书网书单推荐
  • 爱 做 网站大连做网站仟亿科技
  • 前沿技术借鉴研讨-2025.11.4(心率信号)
  • 建站国外平台网站开发待遇怎么样
  • 连接字符串
  • 字典推导式练习题
  • 建站价格会差可以文章上传视频的wordpress主题
  • Hot100之哈希题
  • 上海智能网站建设公司品牌策划公司排名
  • MATLAB基于改进云物元的模拟机协同训练质量评价
  • 做淘宝客建网站用什么推广的方式
  • 广州网站模板建站传媒公司名字大全霸气
  • 昆明网站制作温州企业网站开发
  • 网站域名实名制网站建设常用代码
  • 云南工程建设总承包公司网站all in one wordpress
  • Vendor Invoice Management with SAP学习笔记-第一章 第二章
  • [C++] 时间处理库函数 | `tm`、`mktime` 和 `localtime`
  • 做网站和维护要多少钱wordpress课程管理系统
  • 电商网站开发报价单格斗网页游戏大全
  • 博罗网站设计公司做网络推广有哪些平台
  • 如何建设旅游网站wordpress 子主题开发
  • 北京微网站建设设计服务公司网站备案撤销
  • 建设网站用什么软件发布网站建设信息
  • 想做外贸做哪些网站php笑话网站源码
  • 常用CMake指令
  • php免费网站源码瀑布流网站源码
  • 实战营销型网站建设备案信息查询
  • Spring Boot3零基础教程,消息传递是响应式核心,笔记103
  • 南京设计网站的公司在腾讯云怎样建设网站