【问题标题】:Swift - How to erase generics from a type?Swift - 如何从类型中删除泛型?
【发布时间】:2021-03-02 07:21:47
【问题描述】:

我需要像这样声明一个数组:

var cups: [Cup<Drink>] = []

Cup 是一个结构,Drink 是一个协议,但我收到以下错误:

协议类型“Drink”的值不能符合“Drink”;只有结构/枚举/类类型可以符合协议

我知道协议类型 'Drink' 可以通过 AnyDrink 结构擦除,流式代码就是一个示例。

但实际上associatetypeSelf和static-method(非final类的情况下采用Drink,比如协议Equatable带有static方法==) 用于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()
    }
}

【问题讨论】:

标签: swift generics protocols type-erasure


【解决方案1】:

提问: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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多