[英]How to constrain a Swift generic type parameter to be any protocol and another parameter to conform to it?
我正在嘗試為依賴注入創建一個屬性包裝器:
@propertyWrapper struct Dependency<T> {
private(set) var wrappedValue: T
init() {
wrappedValue = Dependencies.shared.resolve()
}
}
final class Dependencies {
static let shared = Dependencies()
private var dependencies = [String: AnyObject]()
func register<T, P>(_ dependency: T, as: P.Type) {
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!
}
}
目的是注冊一個符合協議的對象,然后根據協議類型查找它。
例如:
protocol Foo {
func foo() -> String
}
class Bar: Foo {
func foo() -> String {
"Hello World!"
}
}
Dependencies.shared.register(Bar(), as: Foo.self)
struct Test {
@Dependency var a: Foo
}
let t = Test()
print(t.a.foo())
這按預期工作 - 打印“Hello World!”
但是,我也可以這樣做:
Dependencies.shared.register("not a Bar", as: Foo.self)
因為 String 不符合 Foo ,所以前提條件就失效了。
我想要做的是約束func register<T, P>(_ dependency: T, as: P.Type)
以便 T 必須符合 P。
類似於register<T: P, P>(_ dependency: T, as: P.Type)
- 這顯然不起作用。
這甚至可能嗎?
我認為此更改必須符合您的期望:
func register<T>(_ dependency: T, as dependencyType: T.Type) {
let key = String(describing: dependencyType)
dependencies[key] = dependency as AnyObject
}
(其余代碼保持不變。)
然后這行打擾你不編譯( Cannot convert value of type 'String' to expected argument type 'Bar'
):
Dependencies.shared.register("not a Bar", as: Bar.self)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.