簡體   English   中英

如何將 Swift 泛型類型參數約束為任何協議和另一個參數以符合它?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM