例如,假设一家披萨店有两种不同类型的披萨:
struct SmallPizza {
var radius: Int
}
struct LargePizza {
var diameter: Int
}
假设他们想使用上述类型创建不同的比萨饼,两者都符合相同的协议。你会这样做:
protocol Pizza {
associatedtype PizzaType
var pizzaType: PizzaType { get set }
var name: String { get set }
}
struct PizzaOne: Pizza {
var pizzaType: SmallPizza
var name: String
}
struct PizzaTwo: Pizza {
var pizzaType: LargePizza
var name: String
}
在此之前,一切都可以无缝运行。现在他们想创建一个 PizzaManager 来获取某个 ID 的披萨:
struct PizzaManager {
let pizzaOne = PizzaOne(pizzaType: SmallPizza(radius: 5), name: "Margherita")
let pizzaTwo = PizzaTwo(pizzaType: LargePizza(diameter: 30), name: "Quattro Formaggi")
// This functions shows the concept I would like to achieve, also if it doesn't work.
func getPizza(forID id: Int) -> Pizza {
if id == 1 {
return pizzaOne
} else {
return pizzaTwo
}
}
}
使用这种方法会引发一个错误,即
可以理解:Protocol 'Pizza' can only be used as a generic constraint because it has Self or associated type requirements
。
我尝试过的其他事情:
func getPizza<T: Pizza>(forID: identifier) -> T {...}
。这不会引发错误,但也不是解决方案,因为调用者需要指定确切的类型,如 let result: PizzaOne = pizzaManager.getPizza(forID: 1)
。这不能解决问题,因为我不想指定实际类型。Any
。如果我理解正确,使用 Any
也会在需要解包时将问题从函数转移到调用方。func getPizza(forID: identifier) -> some Pizza {...}
。它们实际上听起来像是一个完美的解决方案,但是不透明只允许一个单一返回类型(所以要么是 PizzaOne 要么是 PizzaTwo)。问题:
我想从函数中返回 PizzaOne 或 PizzaTwo,因为它们是符合 Pizza 的“某种”类型。所以在那之后,只需访问 Pizza 协议定义的属性,从而包含在符合 Pizza 协议的类型中。
我很确定这不能用不透明的返回类型来完成,因为它们只允许返回一种类型。也许这也不是 Swift 的功能,或者我误解了什么? 有没有其他方法可以解决这个问题?
希望您在阅读比萨饼时不会太饿;)。任何帮助将不胜感激!