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

Swift如何约束泛型参数,确保注册实例遵循指定protocol?

解决方案

你要的约束完全可以实现,只需要调整泛型约束的书写位置即可:你尝试的register<T: P, P>(_ dependency: T, as: P.Type)语法报错,是因为泛型参数P的声明顺序在T之后,无法在声明T时直接用未完成声明的P做约束,把约束移到where子句就可以正常运行。

修改后的register方法如下:

func register<T, P>(_ dependency: T, as: P.Type) where T: P {
  let key = String(describing: P.self)
  dependencies[key] = dependency as AnyObject
}

效果验证

修改完成后,不符合协议要求的注册调用会直接在编译阶段被拦截,不会到运行时才触发崩溃。你提到的非法调用Dependencies.shared.register("not a Bar", as: Foo.self)会直接触发编译错误:Instance method 'register' requires that 'String' conform to 'Foo',完全符合你的需求。

修改后的完整Dependencies类代码:

final class Dependencies {
  static let shared = Dependencies()
  private var dependencies = [String: AnyObject]

  func register<T, P>(_ dependency: T, as: P.Type) where T: P {
    let key = String(describing: P.self)
    dependencies[key] = dependency as AnyObject
  }

  func resolve<T>() -> T {
    let key = String(describing: T.self)
    let dependency = dependencies[key] as? T
    precondition(dependency != nil, "No dependency found for \(key)! must register a dependency before resolve.")
    return dependency!
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:45:00