我有以下
protocol FooPresentable {
var bar: BarPresentable { get }
}
protocol BarPresentable {
}
class Foo {
let bar: Bar
}
extension Bar: BarPresentable {
}
extension Foo: FooPresentable {
}
我得到錯誤Foo
不符合FooPresentable
。是否可以通過讓編譯器知道所有s 都符合來Foo
符合FooPresentable
Bar
BarPresentable
uj5u.com熱心網友回復:
protocol FooPresentable {
var bar: BarPresentable { get }
}
為了Foo
符合FooPresentable
,它的bar
屬性的型別必須是BarPresentable
,這與具有bar
型別符合的屬性不同BarPresentable
。該型別BarPresentable
表示符合 的任何BarPresentable
型別:
struct Bar: BarPresentable {}
struct Baz: BarPresentable {}
let aBarPresentable: BarPresentable = Bar()
aBarPresentable = Baz()
您可能想要的是關聯型別:
protocol FooPresentable {
associatedtype BarBarPresentable: BarPresentable
var bar: BarBarPresentable { get }
}
這意味著A
符合的型別FooPresentable
必須具有一個屬性,該屬性具有特定于符合bar
的型別 ( ) 。我認為最好用一個例子來解釋:TheBarPresentable
A
BarPresentable
class Foo {
let bar: Bar
init(bar: Bar) { self.bar = bar }
}
extension Foo: FooPresentable {
typealias BarBarPresentable = Bar
}
事實上,您不需要顯式typealias
宣告,因為 Swift 可以為您推斷:
extension Foo: FooPresentable {}
uj5u.com熱心網友回復:
FooPresentable
有一個關聯的型別。
protocol FooPresentable {
associatedtype Bar: BarPresentable
var bar: Bar { get }
}
class Foo {
let bar: Module.Bar = .init()
}
uj5u.com熱心網友回復:
不是你這樣做的方式,不。您撰寫了一個協議,上面寫著:為了符合我的要求,宣告一個實際宣告bar
為BarPresentable的變數。你的 Foo 不會那樣做;它宣告了一個宣告為 Bar 的變數bar
,這不是一回事。
您想要的是一個泛型協議,其中泛型被限制為BarPresentable的采用者。
這是一個完整的編譯示例:
protocol FooPresentable {
// this says: `bar` must be declared as a type that adopts BarPresentable
associatedtype T: BarPresentable
var bar: T { get }
}
protocol BarPresentable {
}
struct Bar {}
struct Foo {
// behold, `bar` _is_ declared as a type that adopts BarPresentable
let bar: Bar
}
extension Bar: BarPresentable {
}
extension Foo: FooPresentable {
}
uj5u.com熱心網友回復:
您必須使用存在型別或associatedtype
protocol FooPresentable {
associatedtype B : BarPresentable
var bar: B { get }
}
或者
protocol FooPresentable {
var bar: any BarPresentable { get }
}
哪個正確取決于您的實際用例。
查看 Swift 中的設計協議介面
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/526027.html
標籤:迅速