如何在协议数组中指定特定协议

问题描述 投票:0回答:1

我有一个协议,它的属性是另一个协议。我有一些实现该协议的结构,我对它们很满意。但是,我想要一个协议数组,但指定内部协议始终是特定类型。

如果我展示一些示例代码可能会更容易:

protocol MyCategory {
    var displayTitle: String {get}
}

enum Category1: MyCategory {
    case person
    case place
    case thing
    
    var displayTitle: String {
        switch self {
           ...
        }
    }
}
enum Category2: MyCategory {
    case animal
    case vegetable
    case mineral
    
    var displayTitle: String {
        switch self {
           ...
        }
    }
}

protocol FieldModel {
    var category: MyCategory { get }
    var name: String { get }
}

struct IntFieldModel: FieldModel {
    let category: MyCategory
    let name: String
    let value: Int
}

struct StringFieldModel: FieldModel {
    let category: MyCategory
    let name: String
    let value: String
}

struct Category1ConsolidatedResults {
    let fields: [FieldModel]
}

我希望能够告诉

Category1ConsolidatedResults
fields
中的每个项目都属于
FieldModel
类型,而且每个
category
中的每个
FieldModel
都属于
Category1
类型。

我尝试使用泛型和

associatedtype
做一些事情,但我不知道如何将类型传递到
FieldModel
中的
Category1ConsolidatedResults
协议中。相反,我收到错误“使用协议‘FieldModel’作为类型必须写成‘any FieldModel’”。

有没有办法将类型传递给通用协议?

swift swift-protocols
1个回答
0
投票

在这种情况下尝试使用

associatedtype
时,你是对的。但是,我相信您缺少对
Category1ConsolidatedResults
的限制。你可以尝试这个方法:

protocol FieldModel {
    associatedtype Category: MyCategory //<- here
    var category: Category { get }
    var name: String { get }
}

然后在这些 Field 模型实现上添加通用约束:

struct IntFieldModel<Category: MyCategory>: FieldModel {
    let category: Category
    let name: String
    let value: Int
}
...

最后,

Category1ConsolidatedResults
需要所有
fields
FieldModel
并且
MyCategory
Category1

struct Category1ConsolidatedResults<T: FieldModel> where T.Category == Category1 {
    let fields: [T]
}

现在您可以在定义时将

Category1ConsolidatedResults
Category1
联系起来。

let result = Category1ConsolidatedResults<IntFieldModel<Category1>>(fields: [
    .init(category: Category1.person, name: "", value: 1),
    ...
])
© www.soinside.com 2019 - 2024. All rights reserved.