在 Swift 泛型上切换大小写无法识别对象类型

Switch case on Swift generics not able to identify the object type

我正在显示一个表视图,其中包含使用以下代码生成的列表。 UI 已正确填充。但是在 did select 方法上,调用在一般情况下不匹配。

@objc public protocol ListProtocol {}


class EmptyListProtocol:ListProtocol {
    let message:String
    
    init(message:String){
        self.message = message
    }
}


class ListItemStrategy<T>: ListProtocol{
    let object:T
    
    init(listitem:T) {
        self.object = listitem
    }
}

struct CartInfo {
    let card_id : String
    let productname: String
    let purchasedate:String
}

struct ProductOnSale {
    
    let product_id:String
    let product_name:String
    let store_id:String
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let item = self.tablelist[indexPath.row]
        switch item {
        case is ListItemStrategy<Any>:
            print("didtap")            
        case is EmptyListProtocol: break
        default:
            break
     }
}

var table list : [ListProtocol] = []

如果购物车 selected 或新购买的产品 selected,我无法特别检测到。

检查类型时,您需要了解 SomeGeneric 是一种特定类型,您不能在此处使用协议 Any 作为某种东西表示泛型类型的 any 实现。

这意味着您的 switch 需要类似于

switch item {
    case is ListItemStrategy<ProductOnSale>:
        ...
    case is ListItemStrategy<CartInfo>:
        ...
    case ...
}

我假设你想访问特定的对象,这意味着你需要输入 case item 所以最好跳过开关并使用 if let 直接转换

let item = self.tablelist[indexPath.row]

if let cartInfo = item as? ListItemStrategy<CartInfo> {
    ...
} else if let productOnSale = item as? ListItemStrategy<ProductOnSale> {
    ...
} else if let ... {
    ...
}

这是一个简单的例子

let tableList : [ListProtocol] = [
    ListItemStrategy(listitem: ProductOnSale(product_id: "product1", product_name: "", store_id: "")),
    ListItemStrategy(listitem: CartInfo(card_id: "card1", productname: "", purchasedate: "")),
    ListItemStrategy(listitem: ProductOnSale(product_id: "product2", product_name: "", store_id: "")),
    ListItemStrategy(listitem: EmptyListProtocol(message: "Empty"))
]

for item in tableList {
    if let cartInfo = item as? ListItemStrategy<CartInfo> {
        print(cartInfo.object.card_id)
    } else if let productOnSale = item as? ListItemStrategy<ProductOnSale> {
        print(productOnSale.object.product_id)
    } else if let emptyMessage = item as? ListItemStrategy<EmptyListProtocol> {
        print(emptyMessage.object.message)
    }
}