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

Swift中如何定义元素为遵循Equatable协议的泛型类型数组?

解决Swift中混合泛型类型数组的问题

你遇到的核心问题是:File<T: Equatable>是一个泛型类,当你用不同的T(比如String、Int)实例化它时,得到的是完全不同的具体类型(File<String>和File<Int>不是同一个类型),所以Swift不允许直接把它们放在同一个[File]数组里——因为File本身是泛型,必须指定具体的类型参数。

正确解决方案:用非泛型协议抽象公共行为

我们可以定义一个非泛型的协议,提取Folder需要用到的File的公共属性和方法,让所有File<T>实例都遵循这个协议,这样就能把它们存入同一个协议类型的数组中。

步骤1:定义非泛型协议

protocol FileProtocol {
    var visible: Bool { get set }
    // 提供当前行的字符串描述,满足你拼接输出的需求
    var currentLineDescription: String { get }
}

步骤2:让File<T>遵循协议

修改你的File类,实现协议要求的属性:

class File<T: Equatable>: FileProtocol {
    var lines = [T]()
    var lineCursor: Int = 0
    var currentLine: T {
        get { return lines[lineCursor] }
        set { lineCursor = lines.index(where: { $0 == newValue }) ?? 0 }
    }
    var visible = true
    
    // 实现协议的属性,把泛型的currentLine转成字符串描述
    var currentLineDescription: String {
        return String(describing: currentLine)
    }
}

步骤3:修改Folder的数组类型

把files的类型改成[FileProtocol],这样就能容纳任何遵循该协议的File<T>实例:

class Folder {
    var files = [FileProtocol]()
    
    func currentLinesFromVisibleFiles() -> String {
        return files.filter({ $0.visible })
            .map({ $0.currentLineDescription })
            .joined(separator: "/")
    }
}

测试代码

现在你的测试代码可以正常运行,输出期望的"string/489/true":

var stringFile = File<String>()
stringFile.lines = ["strong", "string", "a", "b", "c"]
stringFile.currentLine = "string"
stringFile.visible = true

var intFile = File<Int>()
intFile.lines = [6, 12, 0, 489]
intFile.currentLine = 489
intFile.visible = true

var doubleFile = File<Double>()
doubleFile.lines = [92.12, 4.9753, 1.6]
doubleFile.currentLine = 92.12
doubleFile.visible = false

var boolFile = File<Bool>()
boolFile.lines = [true, false]
boolFile.currentLine = true
boolFile.visible = true

var folder = Folder()
folder.files = [stringFile, intFile, doubleFile, boolFile]

let output = folder.currentLinesFromVisibleFiles()
print(output) // 输出:"string/489/true"

为什么你之前的尝试都失败了?

  • [File<Any>]:Any没有遵循Equatable协议,不符合File<T>的泛型约束
  • [File<Any & Equatable>]:Swift不允许把带有Self关联类型的协议(比如Equatable)当作具体类型使用,Any & Equatable无法作为合法的泛型参数
  • 其他写法要么是语法错误(比如[File<Any: Equatable>]),要么是传入了不符合约束的类型(比如元组类型不遵循Equatable)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:27:40