您好,我想構建如下所示的內容:
protocol BaseEntity: Identifiable {
var id: UUID { get set }
}
protocol DataStore {
associatedtype T: BaseEntity
typealias CompleteHandler<T> = ((Result<T, Error>) -> Void)
func read(with id: T.ID, completion: CompleteHandler<T>)
}
但在具體實作中,我想利用協議UUID中定義的BaseEntity:
class Storage<Entity: BaseEntity>: DataStore {
func read(with id: Entity.ID, completion: CompleteHandler<Entity>) {
// here, how to use that id as a UUID?
}
}
我不知道該怎么做,定義必須有一個物件符合BaseEntity并希望UUID id在具體實作中使用該屬性。我不想這樣做:
func read(with id: Entity.ID, completion: CompleteHandler<Entity>) {
guard let uuid = id as? UUID else {
return
}
// more code goes here...
}
我應該怎么做?
uj5u.com熱心網友回復:
好吧,基本上在這個實作中缺少任何具體型別是編譯器找出Entity.ID型別的麻煩。
這可以通過Entity在您的實作中不使用泛型型別來顯示Storage,如下所示:
struct MyEntity: BaseEntity {
var id: UUID
}
class Storage: DataStore {
func read(with id: MyEntity.ID, completion: CompleteHandler<MyEntity>) {
print(id.uuidString) // <- `id` is of `UUID` type
}
}
解決方案 1:為了幫助編譯器理解Entity.ID型別,您可以有條件地遵守DataStore協議,宣告它Entity.ID始終是UUID型別(這實際上是您在實作中想要的):
class Storage<Entity: BaseEntity>: DataStore where Entity.ID == UUID {
func read(with id: Entity.ID, completion: CompleteHandler<Entity>) {
print(id.uuidString) // again this line passes compilation
}
}
解決方案 2:更好的是,您可以BaseEntity通過宣告它ID始終是UUID型別來條件約束您的協議。這樣你就不需要改變你的Storage實作:
protocol BaseEntity: Identifiable where ID == UUID {}
// or using the following which is also the same
protocol BaseEntity: Identifiable<UUID> {}
class Storage<Entity: BaseEntity>: DataStore {
func read(with id: Entity.ID, completion: CompleteHandler<Entity>) {
print(id.uuidString) // again this line passes compilation
}
}
解決方案 3:另一種可能更適合您的背景關系的解決方案是轉換BaseEntity為類。這樣你也不需要改變你的Storage實作:
class BaseEntity: Identifiable {
var id: UUID
init(id: UUID) {
self.id = id
}
}
class Storage<Entity: BaseEntity>: DataStore {
func read(with id: Entity.ID, completion: CompleteHandler<Entity>) {
print(id.uuidString) // again this line passes compilation
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/528368.html
標籤:迅速仿制药可识别的
下一篇:通過列舉值參考型別或類?
