Swift 如何使用两个枚举变量实现可识别

Swift 如何使用两个枚举变量实现可识别,swift,identity,swift-protocols,hashable,identifiable,Swift,Identity,Swift Protocols,Hashable,Identifiable,使用Swift 5.3,如何通过使结构的标识取决于两个枚举变量的组合,在结构上实现可识别协议 所讨论的代码很简单 struct Card: Identifiable { let suit: Suit let rank: Rank enum Suit { case spades, clubs, diamonds, hearts } enum Rank: Int { case one = 1, two, th

使用Swift 5.3,如何通过使结构的标识取决于两个枚举变量的组合,在结构上实现
可识别
协议

所讨论的代码很简单

struct Card: Identifiable {
    let suit: Suit
    let rank: Rank
    
    enum Suit {
        case spades, clubs, diamonds, hearts
    }
    
    enum Rank: Int {
        case one = 1, two, three, four, five, six, seven, jack, queen, king
    }
}

上述结构尚不符合
可识别
协议。我如何将其身份实现为其
套装
等级
(仅创建一次)的独特组合?本质上,它的身份可以是“黑桃-1”或“钻石杰克”。此外,如果可能,我希望将
rank
保留为
Int
类型,以便以后进行算术运算。提前谢谢你

由于此类型由其值的组合精确定义,因此它是自己的标识符。因此,只要卡是可散列的,它就可以识别自己:

extension Card: Hashable, Identifiable {
    var id: Self { self }
}

Suit
String
一致,并将它们组合起来以创建唯一标识符
String

struct Card: Identifiable {

    var id: String { "\(suit.rawValue)\(rank.rawValue)" }

    let suit: Suit
    let rank: Rank

    enum Suit: String {
        case spades, clubs, diamonds, hearts
    }
    enum Rank: Int {
        case one = 1, two, three, four, five, six, seven, jack, queen, king
    }
}

注意:这不能适用于所有场景。虽然这在这个特殊的地方很好用。因为我们使用两个字符串的串联来计算
对象的
id

这是可行的,但在一般情况下应用时必须小心。根据缝合在一起的值,可能会意外引入标识符冲突。假设有一个名和姓字段
Person(firstName:“ab”,lastName:“c”)
将具有与
Person(firstName:“a”,lastName:“bc”)相同的标识符
@是的,这不能概括。虽然这在这个特定的场景中非常有效,但对于其他成员来说,这可能是错误的。可能应该在前面加上一句警告的话。:)@这是一种减少错误的可能方法。但对于@Alexander提到的场景,这仍然不是万无一失的<代码>人物(名字:“a.b”,姓氏:“c”)和
人物(名字:“a”,姓氏:“b.c”)
将具有相同的id。@NewDev-Yup,罗布的答案是正确的。对于正在寻找的人来说,这只是一种选择。这有局限性,也有这里讨论的局限性。所以我认为这对其他人来说是一个很好的启示。这就是为什么我不打算删除它,即使是以降低投票率为代价。嘿,Rob,如果说这可以推广到所有具有稳定的、仅公开成员的结构,对吗?它们的身份是由它们的值定义的,不同于类实例的身份在我看来不是这样的。默认情况下,结构没有任何标识。他给了他们一个,说这个系统中正好有一个。例如,在一副牌中,正好有一个钻石之王。如果你看到另一张卡,它实际上是同一张卡,而不仅仅是一张等价/可替代(即,同等)的卡。如果那不是真的,那就是谎言。这对ForEach循环有着重要的影响(我看到人们总是在列表中的元素不一定是唯一的时候使用
id:\.self
。直到它不存在,它才有点“工作”)