我有一個存在于我的應用程式中的物件(比如一個用戶物件),我想發布它(因為某些 UI 依賴于它)。由于 Liskov 替換原則,我不想將它作為 EnvironmentObject 傳遞,所以我決定制作一個包裝器。像這樣的東西:
protocol HasUser: ObservableObject {
var user: String { get }
}
class HasUserWrapper: HasUser {
var user: String { userGetter() }
private let userGetter: () -> String
let objectWillChange: AnyPublisher<Void, Never>
init<UO: HasUser>(wrapping userObject: UO) {
self.objectWillChange = userObject
.objectWillChange
.map { _ in () }
.eraseToAnyPublisher()
self.userGetter = { userObject.user }
}
}
extension HasUser {
func eraseToHasUserWrapper() -> HasUserWrapper {
HasUserWrapper(wrapping: self)
}
}
class ConcreteHasUser: HasUser {
@Published var user: String = "john"
}
struct UserView {
@ObservedObject var hasUser: HasUserWrapper = ConcreteHasUser().eraseToHasUserWrapper()
var body: some View {
Text(hasUser.user)
}
}
現在,我想讓這個包裝器通用。所以我開始了這樣的事情:
protocol HasThing: ObservableObject {
associatedtype Thing
var thing: Thing { get }
}
class HasThingWrapper<Thing>: HasThing {
var thing: Thing { thingGetter() }
private let thingGetter: () -> Foo
let objectWillChange: AnyPublisher<Void, Never>
init<HasThingType: HasThing>(wrapping hasThing: HasThingType) {
self.objectWillChange = hasThing
.objectWillChange
.map { _ in () }
.eraseToAnyPublisher()
self.thingGetter = { hasThing. }
}
}
extension HasThing {
func eraseToThingWrapper() -> HasThingWrapper<Thing> {
HasThingWrapper(wrapping: self)
}
}
protocol HasString: HasThing {
var thing: String { get }
}
class StringHolder: HasString {
@Published var thing: String = "hello"
}
我如何告訴編譯器包裝器內的泛型型別 Thing 應該與 HasThing 協議中的關聯型別 Thing 匹配?
uj5u.com熱心網友回復:
如果我理解正確,您只需要在以下內容中添加一個通用約束init:
init<HasThingType: HasThing>(wrapping hasThing: HasThingType)
where HasThingType.Thing == Thing
{
...
// then you can do:
self.thingGetter = { hasThing.thing }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426086.html
上一篇:泛型:使用派生型別傳遞映射
下一篇:Int32和int的泛型方法區別
