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

Swift中创建通用转换管道遇泛型问题,如何实现可复用?

Swift 类型擦除实现多类型转换器管道

你遇到的核心问题是带关联类型的协议无法直接作为数组元素类型:每个遵循协议的结构体(比如LowercaseTransformation和ReverseTransformation)都是独立的具体类型,而Swift数组要求所有元素必须是同一类型,因此直接将不同转换器放入数组会导致类型歧义或不兼容。

通过类型擦除技术可以解决这个问题——将不同类型的转换器包装成统一的类型,既能放进同一个数组,又能保留泛型的灵活性和可复用性。以下是完整实现:

import Foundation

protocol Transformation {
    associatedtype Target
    func transform(_ input: Target) -> Target
}

struct LowercaseTransformation: Transformation {
    func transform(_ input: String) -> String {
        input.lowercased()
    }
}

struct ReverseTransformation: Transformation {
    func transform(_ input: String) -> String {
        String(input.reversed())
    }
}

// 类型擦除包装器:统一所有处理同一Target类型的Transformation实例
struct AnyTransformation<Target>: Transformation {
    private let _transform: (Target) -> Target
    
    init<Transformer: Transformation>(_ transformer: Transformer) where Transformer.Target == Target {
        _transform = transformer.transform
    }
    
    func transform(_ input: Target) -> Target {
        _transform(input)
    }
}

// 修改后的Pipeline:以Target为泛型参数,接受统一类型的转换器数组
struct Pipeline<Target> {
    let transformations: [AnyTransformation<Target>]
    
    func run(_ input: Target) -> Target {
        var output = input
        transformations.forEach { output = $0.transform(output) }
        return output
    }
}

// 测试字符串转换管道
let pipeline = Pipeline(transformations: [
    AnyTransformation(LowercaseTransformation()),
    AnyTransformation(ReverseTransformation())
])
let input = "Hello World"
let output = pipeline.run(input)
print(output) // 输出:dlrow olleh

关键逻辑说明

  1. 类型擦除包装器AnyTransformation

    • 它通过泛型初始化方法,接受任意遵循Transformation协议且Target匹配的转换器实例
    • 内部用闭包捕获原始转换器的transform方法,对外隐藏具体的转换器类型,只暴露统一的接口
  2. 通用管道Pipeline<Target>

    • 不再依赖具体的转换器类型,而是针对目标类型Target设计
    • 只要是处理同一Target的转换器,都可以通过AnyTransformation包装后加入管道
  3. 可复用性扩展
    如果需要支持其他类型的转换(比如Int),只需新增遵循协议的转换器并包装即可:

    struct DoubleTransformation: Transformation {
        func transform(_ input: Int) -> Int {
            input * 2
        }
    }
    
    struct AddOneTransformation: Transformation {
        func transform(_ input: Int) -> Int {
            input + 1
        }
    }
    
    let intPipeline = Pipeline(transformations: [
        AnyTransformation(DoubleTransformation()),
        AnyTransformation(AddOneTransformation())
    ])
    print(intPipeline.run(5)) // 输出:11
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:45:36