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
相关产品推荐
相关产品推荐

