Then库的原理是什么?

一、Then 库的核心原理

Then 库的本质是利用 Swift 的扩展(Extension)和泛型 ,为所有类型(Any)添加一个通用的then方法,该方法接收一个闭包,将对象自身传入闭包供配置,最后返回配置后的对象 ------ 整个过程没有黑魔法,只是对 Swift 语法特性的巧妙封装。

简单来说,它的核心逻辑可以概括为:

plaintext

复制代码
创建对象 → 调用then方法 → 把对象传入闭包($0) → 闭包内配置属性 → 返回原对象

二、Then 库的核心源码拆解

Then 库的源码非常精简(核心代码不足 50 行),我们先看核心实现,再逐行解释:

1. 核心扩展代码(简化版)

swift

复制代码
// 为所有类型添加then方法(泛型约束:Self代表调用者的类型)
public extension Then {
    /// 配置对象并返回自身
    @inlinable
    func then(_ block: (Self) throws -> Void) rethrows -> Self {
        try block(self) // 将自身传入闭包,执行配置逻辑
        return self     // 返回配置后的自身,支持链式调用
    }
    
    /// 无返回值的配置方法(do方法)
    @inlinable
    func `do`(_ block: (Self) throws -> Void) rethrows {
        try block(self)
    }
}

// 让所有类型都遵守Then协议(空协议,仅作为扩展的载体)
public protocol Then {}

// 扩展NSObject(OC对象)默认遵守Then
extension NSObject: Then {}

// 扩展所有值类型(结构体、枚举)默认遵守Then
extension Then where Self: Any {
    @inlinable
    static func then(_ block: (Self) throws -> Void) rethrows -> Self {
        var instance = self // 值类型需要可变副本
        try block(&instance)
        return instance
    }
}
2. 关键代码逐行解释
(1)空协议Then

swift

复制代码
public protocol Then {}
  • 作用:作为扩展的载体 ,让我们可以给所有遵守该协议的类型添加then方法。
  • 为什么用空协议?因为 Swift 不支持直接给Any添加扩展(extension Any {}会报错),通过空协议作为 "标记",让所有类型都遵守它,就能实现 "全局扩展"。
(2)为Then协议添加then方法

swift

复制代码
public extension Then {
    func then(_ block: (Self) throws -> Void) rethrows -> Self {
        try block(self) 
        return self     
    }
}
  • Self:代表调用者的具体类型(比如调用UILabel().then时,Self就是UILabel),保证类型安全。
  • block: (Self) throws -> Void:接收一个闭包参数,闭包的输入是Self类型(即对象自身),无返回值。
  • try block(self):将对象自身传入闭包,执行你写的配置逻辑(比如$0.text = "Hello")。
  • return self:配置完成后返回对象自身,这是链式调用的核心 (比如可以UILabel().then{}.then{})。
  • rethrows:闭包可能抛出异常时,方法会转发异常,保证错误处理的一致性。
(3)do方法

swift

复制代码
func `do`(_ block: (Self) throws -> Void) rethrows {
    try block(self)
}
  • 作用:和then逻辑一致,但无返回值 ,适合给已存在的对象做配置(比如view.do { $0.bgColor = .red })。
  • do是 Swift 关键字,所以用反引号包裹,避免语法冲突。
(4)让所有类型默认遵守Then

swift

复制代码
// OC对象(NSObject子类)默认遵守
extension NSObject: Then {}

// 所有值类型默认遵守
extension Then where Self: Any { ... }
  • 这一步是关键:通过扩展让UIViewUIButton等 NSObject 子类,以及StringInt、自定义结构体等值类型,都自动拥有then方法,无需手动遵守协议。
(5)值类型的特殊处理

swift

复制代码
extension Then where Self: Any {
    static func then(_ block: (Self) throws -> Void) rethrows -> Self {
        var instance = self // 值类型是值传递,需要创建可变副本
        try block(&instance)
        return instance
    }
}
  • 值类型(结构体、枚举)是值传递 ,直接修改self会报错(self默认不可变),所以需要创建可变副本var instance = self,配置完成后返回副本。

三、Then 库的执行流程(以 UIButton 为例)

我们以这段代码为例,拆解执行过程:

swift

复制代码
let btn = UIButton().then {
    $0.setTitle("点击", for: .normal)
    $0.backgroundColor = .blue
}

执行步骤:

  1. UIButton():创建一个UIButton实例(继承自 NSObject,默认遵守 Then 协议)。
  2. 调用then方法,传入闭包{ $0.setTitle(...); $0.backgroundColor = ... }
  3. then方法内部执行block(self):将刚创建的UIButton实例传入闭包,$0就是这个实例。
  4. 闭包内执行属性配置,修改UIButtontitlebackgroundColor
  5. then方法返回配置后的UIButton实例,赋值给btn

四、Then 库的设计巧思

  1. 泛型 + Self :保证类型安全,闭包内$0的类型是调用者的具体类型(比如UIButton),而非Any,所以能享受 Xcode 的自动补全。
  2. 空协议作为扩展载体 :绕开 Swift 不能直接扩展Any的限制,实现 "全局方法" 的效果。
  3. 值类型 / 引用类型兼容:针对值类型(结构体)做了可变副本的特殊处理,保证配置生效。
  4. inline 优化@inlinable关键字让编译器将方法内联到调用处,无额外性能开销。

总结

  1. 核心原理 :通过空协议Then为所有类型扩展then方法,方法内将对象自身传入配置闭包,执行配置后返回自身,实现链式配置。
  2. 关键技术:Swift 扩展(Extension)、泛型(Self)、值类型 / 引用类型的差异化处理。
  3. 本质:没有复杂逻辑,只是对 "创建对象→配置属性→返回对象" 这一通用流程的语法封装,让代码更简洁。
相关推荐
A13247053122 小时前
进程管理入门:查看和控制Linux进程
linux·运维·服务器·网络·chrome·github
The star"'2 小时前
华为云服务系列总结
运维·华为云·云计算
云和数据.ChenGuang2 小时前
openeuler下的git指令集合
linux·运维·数据库·centos
珠海西格电力2 小时前
零碳园区工业园区架构协同方案
运维·人工智能·物联网·架构·能源
奥尔特星云大使2 小时前
使用 Docker 运行 SQL Server 2019
运维·docker·容器·sql server
m0_485614672 小时前
Linux-Dockerfile与Docker Compose
linux·运维·docker
G_H_S_3_3 小时前
【网络运维】MySQL组成与常用工具
运维·网络·mysql
点亮一颗LED(从入门到放弃)3 小时前
Linux驱动之中断(9)
linux·运维·单片机
阎*水3 小时前
Ceph 分布式存储完整实践指南
linux·运维·分布式·ceph