如何将遵循协议的泛型多实现传入SetGame模型结构体?
解决SetGame模型泛型参数适配多特性的问题
你的核心问题在于原SetGame结构体仅定义了单个泛型参数Characteristic,但Set卡牌的四个特性(数量、颜色、形状、填充)是不同的类型,无法通过单一泛型参数复用。需要调整模型的泛型设计,让它支持四个独立的、遵循HasThreeVariations协议的特性类型。
修改后的Model代码
import Foundation // 调整为四个泛型参数,对应卡牌的四个特性 struct SetGame< Attr1: HasThreeVariations, Attr2: HasThreeVariations, Attr3: HasThreeVariations, Attr4: HasThreeVariations > { private var cardArray: Array<Card> struct Card { // 每个特性对应独立的泛型类型 let attribute1: Attr1 let attribute2: Attr2 let attribute3: Attr3 let attribute4: Attr4 } // 示例:生成所有可能的卡牌组合 init() { let allAttr1 = [Attr1.variant1, Attr1.variant2, Attr1.variant3] let allAttr2 = [Attr2.variant1, Attr2.variant2, Attr2.variant3] let allAttr3 = [Attr3.variant1, Attr3.variant2, Attr3.variant3] let allAttr4 = [Attr4.variant1, Attr4.variant2, Attr4.variant3] cardArray = allAttr1.flatMap { attr1 in allAttr2.flatMap { attr2 in allAttr3.flatMap { attr3 in allAttr4.map { attr4 in Card(attribute1: attr1, attribute2: attr2, attribute3: attr3, attribute4: attr4) } } } } cardArray.shuffle() } // 其他游戏逻辑方法(判断Set组合、发牌等)... } protocol HasThreeVariations { associatedtype Variant static var variant1: Variant { get } // 改为静态属性更合理,变体是类型级别的特性 static var variant2: Variant { get } static var variant3: Variant { get } }
修改后的ViewModel代码
import SwiftUI class SSNCSetGame: ObservableObject { // 传入四个具体的特性类型作为泛型参数 @Published private var model: SetGame<ShapeCount, ShapeColor, ShapeStyle, ShapeFill> init() { model = SetGame() } // 数量特性 struct ShapeCount: HasThreeVariations { typealias Variant = NumberOfShapes static var variant1 = NumberOfShapes.one static var variant2 = NumberOfShapes.two static var variant3 = NumberOfShapes.three } enum NumberOfShapes: CaseIterable { case one, two, three } // 颜色特性 struct ShapeColor: HasThreeVariations { typealias Variant = ColorOfShape static var variant1 = ColorOfShape.red static var variant2 = ColorOfShape.green static var variant3 = ColorOfShape.blue } enum ColorOfShape: CaseIterable { case red, green, blue // 可选:转成SwiftUI Color方便视图使用 var uiColor: Color { switch self { case .red: return .red case .green: return .green case .blue: return .blue } } } // 形状特性(补充完整) struct ShapeStyle: HasThreeVariations { typealias Variant = ShapeType static var variant1 = ShapeType.diamond static var variant2 = ShapeType.squiggle static var variant3 = ShapeType.oval } enum ShapeType: CaseIterable { case diamond, squiggle, oval } // 填充特性(补充完整) struct ShapeFill: HasThreeVariations { typealias Variant = FillStyle static var variant1 = FillStyle.solid static var variant2 = FillStyle.striped static var variant3 = FillStyle.outlined } enum FillStyle: CaseIterable { case solid, striped, outlined } // 暴露给视图的模型数据 var cards: [SetGame<ShapeCount, ShapeColor, ShapeStyle, ShapeFill>.Card] { model.cardArray } // 其他视图交互方法... }
关键调整说明
- 泛型参数扩展:将
SetGame从单泛型改为四泛型,每个参数对应卡牌的一个特性,确保不同特性的类型独立性,彻底解决原设计的类型冲突问题。 - 协议优化:将协议中的实例属性改为静态属性,因为特性的变体是类型固有的(比如所有数量特性的变体都是1、2、3),而非实例级别的属性,更符合逻辑。
- ViewModel适配:声明
model时直接传入四个具体的特性类型,完美契合MVVM架构——模型层负责通用游戏逻辑,ViewModel层定义具体的游戏规则(特性变体)。
这样修改后,SetGame模型可以完全复用,后续如果需要定义其他类型的特性,只要遵循HasThreeVariations协议即可。
内容的提问来源于stack exchange,提问作者dve.exe
相关产品推荐
相关产品推荐

