数组 – 当数组在Swift中是Equatable时,为什么数组不符合Equatable?

更新:

从包含Swift 4.1的Xcode 9.3开始,数组相等性按预期工作,原始问题中的代码编译时没有错误.

但是,请参阅接受的答案,因为它提供了更好,更现代的解决方案.

原始问题如下:

当我尝试使用[Post]类型声明一个通用枚举的实例时,我收到一个错误说法

Type ‘[Post]’ does not conform to protocol ‘Equatable’

这是无稽之谈,因为Post符合Equatable,我实际上可以比较两个[Post]实例没有编译错误

在以下示例中,我扩展了Post和Result< T>使用Equatable的类型,然后我做了一些测试:

>测试我可以比较两种帖子类型:好的
>测试我可以比较两个[Post]类型:OK
>测试我可以比较两个结果< Post>类型:好的
>测试我可以比较两个结果< [Post]>类型:错误

import Foundation

struct Post {
    let text: String
}
extension Post: Equatable {}
func ==(lhs: Post,rhs: Post) -> Bool {
    return lhs.text == rhs.text
}


enum Result<T: Equatable> {
    case success(result: T)
    case error
}
extension Result: Equatable {
    static func ==(lhs: Result<T>,rhs: Result<T>) -> Bool {
        switch (lhs,rhs) {
        case let (.success(lhsVal),.success(rhsVal)):
            return lhsVal == rhsVal
        case (.error,.error):
            return true
        default:
            return false
    }
}

func test() {

    // Test 1: Check Post type for equality: OK
    let post1: Post = Post(text: "post 1")
    let post2: Post = Post(text: "post 2")

    if post1 == post2 {
        print("equal posts")
    }

    // Test 2: Check [Post] type for equality: OK
    let arrayOfPosts1: [Post] = [ post1,post2 ]
    let arrayOfPosts2: [Post] = [ post1,post2 ]

    if arrayOfPosts1 == arrayOfPosts2 {
        print("equal arrays of post")
    }

    // Test 3: Check Result<Post> type for equality: OK
    let result1: Result<Post> = Result<Post>.success(result: post1)
    let result2: Result<Post> = Result<Post>.success(result: post2)

    if result1 == result2 {
        print("equal results of post")
    }

    // Test 4: Check Result<[Post]> type for equality: ERROR
    // Compiler error: "Type '[Post]' does not conform to protocol 'Equatable'"
    let arrayResult1: Result<[Post]> = Result<[Post]>.success(result: arrayOfPosts1)
    let arrayResult2: Result<[Post]> = Result<[Post]>.success(result: arrayOfPosts2)

    if arrayResult1 == arrayResult2 {
        print("equal results of array of posts")
    }
}

解决方法

Swift 4.1更新:

随着Swift 4.1中条件一致性的引入,Array现在符合Equatable,所以应该解决问题而不需要求助于任何变通办法.

此外,Swift现在允许类型自动合成Equatable一致性,只要其所有成员都是Equatable,只需将Equatable一致性声明为原始类型定义(不是扩展)的一部分,但不实现其任何要求.这适用于枚举提供的相关值(如果有)是Equatable.

现在可以更简洁地编写此问题的代码,如下所示:

import Foundation

struct Post: Equatable {
    let text: String
}

enum Result<T>: Equatable where T: Equatable {
    case success(result: T)
    case error
}

代码将通过问题中指定的所有测试:

func test() {

    // Test 1: Check Post type for equality: OK
    let post1 = Post(text: "post")
    let post2 = Post(text: "post")

    if post1 == post2 {
        print("equal posts")
    }

    // Test 2: Check [Post] type for equality: OK
    let arrayOfPosts1 = [post1,post2]
    let arrayOfPosts2 = [post1,post2]

    if arrayOfPosts1 == arrayOfPosts2 {
        print("equal arrays of post")
    }

    // Test 3: Check Result<Post> type for equality: OK
    let result1 = Result<Post>.success(result: post1)
    let result2 = Result<Post>.success(result: post2)

    if result1 == result2 {
        print("equal results of post")
    }

    // Test 4: Check Result<[Post]> type for equality: OK
    let arrayResult1: Result<[Post]> = Result<[Post]>.success(result: arrayOfPosts1)
    let arrayResult2: Result<[Post]> = Result<[Post]>.success(result: arrayOfPosts2)

    if arrayResult1 == arrayResult2 {
        print("equal results of array of posts")
    }
}

这是输出

test()
/*
 prints:
 equal posts
 equal arrays of post
 equal results of post
 equal results of array of posts
*/

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...