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