You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中链式泛型推断闭包实现:如何构建通用链式调用接口?

嘿,这事儿我熟!想要实现这种流畅的链式调用,核心就是用泛型类来持有每一步的结果,然后通过方法传递闭包完成值的转换。给你两种方案,一种是通用万能款,另一种是完全贴合你给出的调用语法的定制款,看你需求选!

方案一:通用链式转换类(灵活适配所有类型)

这个方案的优势是不用针对每种类型写特定方法,不管你要转换什么类型,都能用同一个transform方法链式调用,还支持给每个闭包加命名(方便调试或日志)。

class Chainable<Value> {
    private let currentValue: Value
    
    // 初始化方法,持有当前阶段的值
    init(_ value: Value) {
        self.currentValue = value
    }
    
    // 通用转换方法:接收转换闭包,返回新的Chainable实例
    func transform<NewValue>(functionName: String? = nil, _ handler: (Value) -> NewValue) -> Chainable<NewValue> {
        // 如果需要记录函数名,这里可以加日志逻辑
        if let name = functionName {
            print("Executing chain function: \(name)")
        }
        let newValue = handler(currentValue)
        return Chainable(newValue)
    }
    
    // 终结方法:执行最后一步操作,不返回新的链式实例
    func finish(functionName: String? = nil, _ handler: (Value) -> Void) {
        if let name = functionName {
            print("Executing final chain function: \(name)")
        }
        handler(currentValue)
    }
    
    // 快速初始化入口
    static func start(with initialValue: Value) -> Chainable<Value> {
        return Chainable(initialValue)
    }
}

使用示例

Chainable.start(with: "123")
    .transform(functionName: "chainedFunction") { string in
        // 实际项目里建议处理可选值,避免崩溃
        Int(string) ?? 0 + 456
    }
    .transform(functionName: "anotherChain") { number in
        [NSNumber(value: number), String(number)]
    }
    .finish(functionName: "lastInTheChain") { array in
        print("value 1: \(array[0])")
        print("value 2: \(array[1])")
    }
方案二:定制化链式方法(和你的示例语法完全匹配)

如果你想要完全贴合你给出的调用写法(直接用chainedFunction、anotherChain这类命名方法),可以通过给Chainable扩展特定类型的方法来实现:

class Chainable<Value> {
    private let currentValue: Value
    
    init(_ value: Value) {
        self.currentValue = value
    }
    
    // 快速初始化入口
    static func start(with initialValue: Value) -> Chainable<Value> {
        return Chainable(initialValue)
    }
}

// 针对String类型的链式方法:转换为Int
extension Chainable where Value == String {
    func chainedFunction(_ handler: (String) -> Int) -> Chainable<Int> {
        let newValue = handler(currentValue)
        return Chainable(newValue)
    }
}

// 针对Int类型的链式方法:转换为[Any]数组
extension Chainable where Value == Int {
    func anotherChain(_ handler: (Int) -> [Any]) -> Chainable<[Any]> {
        let newValue = handler(currentValue)
        return Chainable(newValue)
    }
}

// 针对[Any]类型的终结方法:执行打印操作
extension Chainable where Value == [Any] {
    func lastInTheChain(_ handler: ([Any]) -> Void) {
        handler(currentValue)
    }
}

使用示例

这时候调用就完全和你想要的一模一样了:

Chainable.start(with: "123")
    .chainedFunction { string in
        Int(string)! + 456 // 注意:实际项目请处理可选值,避免崩溃
    }
    .anotherChain { number in
        [NSNumber(value: number), String(number)]
    }
    .lastInTheChain { 
        print("value 1: \($0[0])") 
        print("value 2: \($0[1])") 
    }
关键原理说明

两种方案的核心逻辑都是用泛型类持有每一步的结果值,每个链式方法接收一个闭包,把当前持有的值传入闭包作为参数,闭包返回的新值会被包装成新的泛型类实例,从而实现链式调用。而终结方法则是直接使用当前值执行操作,不返回新实例,结束链式流程。

内容的提问来源于stack exchange,提问作者Genhain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:06:16