声明协议的属性表明协议只能用作泛型约束,因为它具有Self或关联类型要求。

3
我陷入了一个无法找到解决方案的境地。看到了很多类似的问题,但无法弄清楚。
因此,我有一个视图控制器,它显示两种类型的表格视图列表
1)销售
2)采购
我已经决定同时使用同一个视图控制器。
enum SalesRowType {
    case salesOrderBooking
    case salesInvoicing
    case salesGrossContribution
}

enum PurchaseRowType {
    case purchaseOrders
    case amended_non_amended
    case pending_grn_po
}

并且

// BASE PROTOCOL
 // ListRowType -> has title,image property 
protocol HomeSubItemType:ListRowType {
    associatedtype RowType
    var type:RowType {get}
}
// PURCHASE ITEMS

struct PurchaseSubItem: HomeSubItemType {

    typealias RowType = PurchaseRowType

    var image: UIImage
    var title: String
    var type: PurchaseRowType
}
// SALES ITEMS
struct SalesSubItem : HomeSubItemType {
    var image:UIImage
    var title:String
    var type:SalesRowType
}

在我的视图控制器中,我想根据销售和采购创建数组。
if let type = type {
            switch type {
            case .purchase:
                self.title = "Purchase"
                self.itemList = [
                    PurchaseSubItem(image: UIImage(named: "purchase-orders")!, title: "Purchase Orders", type: .purchaseOrders),
                    PurchaseSubItem(image: UIImage(named: "amended-non")!, title: "Amended/NON-Amended-UNAutho-PO", type: .purchaseOrders),
                    PurchaseSubItem(image: UIImage(named: "purchase-pending")!, title: "Pending GRN PO", type: .purchaseOrders)]

            case .sales:
                self.title = "Sales"

                self.itemList =
                [
                    SalesSubItem(image: UIImage(named: "sales-order-booking")!, title: "Sales Order Booking", type: .salesOrderBooking),
                    SalesSubItem(image: UIImage(named: "sales-invoice")!, title: "Sales Invoicing", type: .salesInvoicing),
                    SalesSubItem(image: UIImage(named: "sale-gross")!, title: "Sales Gross Contribution", type: .salesGrossContribution)]

            default:
                assertionFailure("Only Purchase and sales are handle here")
            }
        }

但是我无法声明数组

var itemList  = [HomeSubItemType]() 
//ERROR HERE

协议“HomeSubItemType”只能用作泛型约束,因为它具有Self或关联类型要求

请帮助我解决这个问题。先感谢您的帮助。


也许我的问题的第一部分可以为您指引方向:https://stackoverflow.com/questions/53796227/create-an-array-of-protocols-with-constrained-associated-types - J. Doe
@J.Doe 谢谢,我会去查看的。 - Prashant Tukadiya
@J.Doe 当我声明数组 [SubItem<Any>] 时,我无法添加类型为 PurchaseRowType.purchaseOrders 的项目,它会显示错误,如 **Cannot assign value of type '[SubItem<PurchaseRowType>]' to type '[SubItem<Any>]'**。有什么帮助吗? - Prashant Tukadiya
为什么不使用 var itemList = [ListRowType]() - vadian
@vadian,我有一个HomeSubItemType,其中包含关联类型RowType,但现在我无法创建数组,因为编译器在装饰时间无法确定RowType - Prashant Tukadiya
显示剩余3条评论
1个回答

2

更新

这是一个完全不同的解决方案,专注于解决问题而不是使用泛型。

首先,我为枚举创建了一个协议,由于它只是将它们分组在一起,所以它是空的。

protocol RowType {}

两个枚举类型都实现了这一点,在此未显示,并且我修改了ListRowType以

protocol ListRowType {
    var title: String {get}
    var image: UIImage {get}
    var type: RowType  {get}
}

并完全跳过了 HomeSubItemType

SubItem 现在

struct SubItem: ListRowType {
    var type: RowType
    var title: String
    var image: UIImage   
}

以及我的测试代码

var itemList  = [ListRowType]()
let sale = SubItem(type: SalesRowType.salesInvoicing, title: "XYZ", image: UIImage())
itemList.append(sale)

let purchase = SubItem(type: PurchaseRowType.purchaseOrders, title: "ABC", image: UIImage())
itemList.append(purchase)

如果愿意的话,当然可以使用原始的PurchaseSubItemSalesSubItem而不是SubItem


我用一个通用结构体替换了这两个结构体

struct SubItem<T>: HomeSubItemType {    
    typealias RowType = T

    var type: T
    var title: String
    var image: UIImage
}

并且像这样使用它

var itemList  = [SubItem<SalesRowType>]()
var item = SubItem(type: SalesRowType.salesInvoicing, title: "XYZ", image: UIImage())

itemList.append(item)

所以你需要两个数组,这可能是最好的方式。如果你非得只有一个数组,那么就声明它吧。
var itemList  = [Any]()

谢谢,但我知道J.Doe建议的解决方案。这个解决方案在你的代码中对销售很好用,但是它不能同时适用于采购和销售,我得到了“无法将类型'[SubItem<PurchaseRowType>]'的值分配给类型'[SubItem<SalesRowType>]'” 的错误提示。 - Prashant Tukadiya
是的,使用 Any 是可以正常工作的。但这似乎是一种 hack 的方法。我肯定会给你一个赞,但如果你能提供更好的解决方案,我会接受这个答案 :) - Prashant Tukadiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接