Swift - 如何从类型中删除泛型?
Swift - How to erase generics from a type?
我需要像这样声明一个数组:
var cups: [Cup<Drink>] = []
Cup
是一个结构,Drink
是一个协议,但我得到以下错误:
Value of protocol type 'Drink' cannot conform to 'Drink'; only struct/enum/class types can conform to protocols
我知道协议类型 'Drink' 可以被 AnyDrink
结构擦除,流动的代码就是一个例子。
但实际上,Type-Erasure在associatetype
、Self
和static-method(非final的情况下class采用Drink
,比如协议Equatable
和静态方法==
)在Drink
.
中使用
我的问题是:有没有更好的方法来声明cups
数组?
或:有没有简单的方法来进行类型擦除?它应该是一个内置功能。
protocol Drink {
...
}
struct AnyDrink: Drink {
let drink: Drink
...
}
struct Water: Drink {
...
}
struct Coffee: Drink {
...
}
struct Tea: Drink {
...
}
struct Cup<T: Drink> {
private(set) var drink: T?
mutating func bottomUp() {
drink = nil
}
}
struct Waiter {
var cups: [Cup<AnyDrink>] = []
mutating func makeACupOfSth(_ cup: Cup<AnyDrink>) {
cups.append(cup)
}
mutating func pleaseGiveMeACupOfSthToDrink() -> Cup<AnyDrink> {
return cups.removeFirst()
}
static func excuse(_ customer: Customer) -> Waiter {
return Waiter()
}
}
struct Customer {
var me: Self { self }
func drink() {
var waiter = Waiter.excuse(me)
var cup = waiter.pleaseGiveMeACupOfSthToDrink()
cup.bottomUp()
}
}
问题:Is there any better way to declare the cups array
你可以像这样使用另一个名为 DrinkGeneric 的协议,并通过 Cup Struct 实现它:
protocol DrinkGeneric {
func smaple()
func typOfDrink() -> Drink.Type
}
struct Cup<T: Drink>: DrinkGeneric {
public var drink: T?
mutating func bottomUp() {
drink = nil
}
public func typOfDrink() -> Drink.Type {
return type(of: drink!)
}
func smaple() {
print("sample")
}
}
然后创建一个类型为 DrinkGeneric 的数组,如下所示:
var cups: [DrinkGeneric] = [Cup<Water>(drink: Water.init()), Cup<Tea>(drink: Tea.init())]
支票类型:
if type(of: cups[0].typOfDrink()) == Water.self {
// any work
}
我需要像这样声明一个数组:
var cups: [Cup<Drink>] = []
Cup
是一个结构,Drink
是一个协议,但我得到以下错误:
Value of protocol type 'Drink' cannot conform to 'Drink'; only struct/enum/class types can conform to protocols
我知道协议类型 'Drink' 可以被 AnyDrink
结构擦除,流动的代码就是一个例子。
但实际上,Type-Erasure在associatetype
、Self
和static-method(非final的情况下class采用Drink
,比如协议Equatable
和静态方法==
)在Drink
.
我的问题是:有没有更好的方法来声明cups
数组?
或:有没有简单的方法来进行类型擦除?它应该是一个内置功能。
protocol Drink {
...
}
struct AnyDrink: Drink {
let drink: Drink
...
}
struct Water: Drink {
...
}
struct Coffee: Drink {
...
}
struct Tea: Drink {
...
}
struct Cup<T: Drink> {
private(set) var drink: T?
mutating func bottomUp() {
drink = nil
}
}
struct Waiter {
var cups: [Cup<AnyDrink>] = []
mutating func makeACupOfSth(_ cup: Cup<AnyDrink>) {
cups.append(cup)
}
mutating func pleaseGiveMeACupOfSthToDrink() -> Cup<AnyDrink> {
return cups.removeFirst()
}
static func excuse(_ customer: Customer) -> Waiter {
return Waiter()
}
}
struct Customer {
var me: Self { self }
func drink() {
var waiter = Waiter.excuse(me)
var cup = waiter.pleaseGiveMeACupOfSthToDrink()
cup.bottomUp()
}
}
问题:Is there any better way to declare the cups array
你可以像这样使用另一个名为 DrinkGeneric 的协议,并通过 Cup Struct 实现它:
protocol DrinkGeneric {
func smaple()
func typOfDrink() -> Drink.Type
}
struct Cup<T: Drink>: DrinkGeneric {
public var drink: T?
mutating func bottomUp() {
drink = nil
}
public func typOfDrink() -> Drink.Type {
return type(of: drink!)
}
func smaple() {
print("sample")
}
}
然后创建一个类型为 DrinkGeneric 的数组,如下所示:
var cups: [DrinkGeneric] = [Cup<Water>(drink: Water.init()), Cup<Tea>(drink: Tea.init())]
支票类型:
if type(of: cups[0].typOfDrink()) == Water.self {
// any work
}