微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift中的Equatable协议

我正在努力制作一个简单的游戏实现.所以每个游戏都有正确的答案.答案可以是Int或String.所以我在代码中有的是:

protocol Answer {}
extension Int: Answer {}
extension String: Answer {}

protocol CorrectAnswer {
    var correctAnswer: Answer { get }
}

我有一个游戏需要的协议:

protocol GameDescriber {
    var name: String { get }
    var description: String { get }
    var points: Int { get }
}

并且Game结构的实现:

struct Game: GameDescriber,Equatable,CorrectAnswer {
    var correctAnswer: Answer
    var name: String
    var description: String
    var points: Int

    static func ==(_ lhs: Game,_ rhs:Game) -> Bool {
        if let _ = lhs.correctAnswer as? String,let _ = rhs.correctAnswer as? Int {
            return false
        }

        if let _ = lhs.correctAnswer as? Int,let _ = rhs.correctAnswer as? String {
            return false
        }

        if let lhsInt = lhs.correctAnswer as? Int,let rhsInt = rhs.correctAnswer as? Int {
            if lhsInt != rhsInt {
                return false
            }
        }

        if let lhsstring = lhs.correctAnswer as? String,let rhsstring = rhs.correctAnswer as? String {
            if lhsstring != rhsstring {
                return false
            }
        }

        return lhs.description == rhs.description &&
            lhs.name == rhs.name &&
            lhs.points == rhs.points
    }
}

如果我想添加一个答案类型(让我们说一组Ints)我必须这样做:

extension Array: Answer where Element == Int {}

但困扰我的是Equatable func的实现==我必须覆盖这个以及可能的其他情况.哪个可以戏剧性:)

有没有解决方案,可以更优雅和通用的方式完成吗?

解决方法

首先请注意,您的==实现可以简化为

static func ==(_ lhs: Game,_ rhs:Game) -> Bool {
    switch (lhs.correctAnswer,rhs.correctAnswer) {
    case (let lhsInt as Int,let rhsInt as Int):
        if lhsInt != rhsInt {
            return false
        }
    case (let lhsstring as String,let rhsstring as String):
        if lhsstring != rhsstring {
            return false
        }
    default:
        return false
    }
    return lhs.description == rhs.description &&
        lhs.name == rhs.name &&
        lhs.points == rhs.points
}

所以添加一个答案类型只是意味着添加一个额外的
案件.

问题是编译器无法验证所有可能的情况
答案类型是在你的==函数中处理的,所以这种方法
很容易出错.

我实际上要做的是使用枚举答案而不是
协议,并使该Equatable:

enum Answer: Equatable {
    case int(Int)
    case string(String)
}

请注意,您不必实现==.截至Swift 4.1,
编译器自动合成,参见
SE-0185 Synthesizing Equatable and Hashable conformance.

而现在游戏简化为

struct Game: GameDescriber,CorrectAnswer {
    var correctAnswer: Answer
    var name: String
    var description: String
    var points: Int
}

编译器合成==的地方,认实现比较所有存储的属性是否相等.

添加一个答案类型只需添加一个案例即可
枚举:

enum Answer: Equatable {
    case int(Int)
    case string(String)
    case intArray([Int])
}

没有任何额外的代码.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐