如何處理這個問題?
定義:
protocol NameProtocol {
var rawValue: String { get }
}
struct CatName: NameProtocol {
enum CatNamesEnum: String {
case Tiger, Max, Sam
}
var literal: CatNamesEnum
var rawValue: String {
literal.rawValue
}
}
struct DogName: NameProtocol {
enum DogNamesEnum: String {
case Jack, Toby, Sadie
}
var literal: DogNamesEnum
var rawValue: String {
literal.rawValue
}
}
定義:
protocol AnimalProtocol {
associatedtype Name: NameProtocol
var name: Name { get }
func cry() -> String
}
class Cat: AnimalProtocol {
var name: CatName
func cry() -> String {
return "meow, I am \(name.rawValue)"
}
init(name: CatName) {
self.name = name
}
// some other cat actions...
}
class Dog: AnimalProtocol {
var name: DogName
func cry() -> String {
return "bark, I am \(name.rawValue)"
}
init(name: DogName) {
self.name = name
}
// some other dog actions...
}
上面的代碼是一些定義代碼結構,不應修改。
下面的函式有一些問題:
- 協議
asccociatedtype不能是字典值型別。 - 具有不透明回傳型別的函式不能回傳一些擴展相同協議的不同型別。
// <1>
// Error: Protocol 'AnimalProtocol' can only be used as a generic constraint because it has Self or associated type requirements
let animals: [String: AnimalProtocol] = [
"cat": Cat(name: CatName(literal: .Sam)),
"dog": Dog(name: DogName(literal: .Jack))
// ...
// maybe a lot of animals
]
for (animal, entity) in animals {
print("\(animal): \(entity.cry())")
}
// <2>
// Error: Function declares an opaque return type, but the return statements in its body do not have matching underlying types
func animalCry(animal: String) -> some AnimalProtocol {
switch animal {
case "cat":
return Cat(name: CatName(literal: .Sam))
default:
return Dog(name: DogName(literal: .Toby))
}
}
任何解決方案? 或者串列中不同型別(帶有嵌入泛型型別)的最佳實踐。
uj5u.com熱心網友回復:
您說不應修改定義,但這正是我在這里所做的:
我從AnimalProtocol協議中洗掉了關聯型別,因為它沒有在任何符合型別的其他地方使用
protocol AnimalProtocol {
var name: NameProtocol { get }
func cry() -> String
}
然后我改變了兩者Cat并Dog通過將name兩者中的宣告更改為符合協議
var name: NameProtocol
這解決了字典的問題,并通過將回傳型別從 更改some AnimalProtocol為AnimalProtocol
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311152.html
下一篇:通用編碼型別
