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

如何将泛型类型引用为其继承的父协议类型?

泛型存储协议的可变/只读类型兼容问题解决方案

你的现有协议继承结构完全可以实现需求,不需要取消继承改用关联类型。核心思路是利用MutableStorage继承自ImmutableStorage的特性,通过**存在类型(any)**或泛型约束,让collectItems方法的闭包参数接受只读的ImmutableStorage类型,同时保证类型匹配。

修改后的代码示例

调整collectItems方法的签名,将闭包参数类型改为与当前存储同StorageItem的ImmutableStorage存在类型:

class StorageExample<S: MutableStorage> {
  private var mutableStorage: S
  init(mutableStorage: S) {
    self.mutableStorage = mutableStorage
  }

  // 调整闭包参数为只读的ImmutableStorage类型,约束StorageItem与S一致
  func collectItems(_ collector: (any ImmutableStorage where StorageItem == S.StorageItem) -> [S.StorageItem]) {
    let itemUpdates = collector(mutableStorage) // 可直接传入,因为S遵循ImmutableStorage
    for item in itemUpdates {
      mutableStorage.contents[item.key] = item
    }
  }
}

/// 可读写的存储协议
protocol MutableStorage: ImmutableStorage {
  var contents: [StorageItem.Key: StorageItem] { get set }
}

/// 只读存储协议(仅可查看,不可修改)
protocol ImmutableStorage {
  associatedtype StorageItem: Item
  var contents: [StorageItem.Key: StorageItem] { get }
}

/// 可被存储的Item协议
protocol Item {
  associatedtype Key: Hashable
  associatedtype Data
  var key: Key { get }
  var data: Data { get }
}

关键说明

  1. 类型兼容性:由于MutableStorage继承自ImmutableStorage,S类型的实例天然符合ImmutableStorage协议,因此可以直接传入接受ImmutableStorage的闭包。
  2. 存在类型的作用:any ImmutableStorage where StorageItem == S.StorageItem确保闭包只能访问存储的只读接口,同时约束存储的StorageItem类型与当前类的泛型参数一致,避免类型不匹配。
  3. 语义保留:当前的继承关系清晰表达了“可变存储是只读存储的扩展”这一语义,相比改用关联类型,更符合面向协议设计的原则,也更易维护。

如果需要兼容Swift 5.7以下版本(不支持any关键字),可以改用泛型方法实现相同效果:

func collectItems<I: ImmutableStorage>(_ collector: (I) -> [S.StorageItem]) where I.StorageItem == S.StorageItem {
    guard let immutableStorage = mutableStorage as? I else {
        fatalError("存储类型不匹配")
    }
    let itemUpdates = collector(immutableStorage)
    for item in itemUpdates {
        mutableStorage.contents[item.key] = item
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:39:51