You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将遵循协议的泛型多实现传入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
    }
    
    // 其他视图交互方法...
}

关键调整说明

  1. 泛型参数扩展:将SetGame从单泛型改为四泛型,每个参数对应卡牌的一个特性,确保不同特性的类型独立性,彻底解决原设计的类型冲突问题。
  2. 协议优化:将协议中的实例属性改为静态属性,因为特性的变体是类型固有的(比如所有数量特性的变体都是1、2、3),而非实例级别的属性,更符合逻辑。
  3. ViewModel适配:声明model时直接传入四个具体的特性类型,完美契合MVVM架构——模型层负责通用游戏逻辑,ViewModel层定义具体的游戏规则(特性变体)。

这样修改后,SetGame模型可以完全复用,后续如果需要定义其他类型的特性,只要遵循HasThreeVariations协议即可。

内容的提问来源于stack exchange,提问作者dve.exe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:05:04