更新
从Xcode 9.3开始,包括 Swift 4.1 ,数组相等按预期工作,原始问题中的代码编译时没有错误。
然而,请参阅接受的答案,因为它提供了更好,更现代的解决方案。
原始问题如下:
当我尝试声明类型为[Post]
的通用枚举的实例时,我收到错误消息
类型'[Post]'不符合协议'Equatable'
这是无稽之谈,因为Post
符合Equatable
并且我实际上可以比较两个[Post]
实例而没有编译错误?
在以下示例中,我使用Post
扩展了Result<T>
和Equatable
类型,然后我做了一些测试:
Post
类型:确定 [Post]
类型:确定 Result<Post>
类型:确定 Result<[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")
}
}
答案 0 :(得分:5)
Swift 4.1更新:
随着Swift 4.1中条件一致性的引入,$public = "My public key";
$private = "My private key";
require_once 'classes/bittrex.php';
$request = new Bittrex($public, $private);
$markets = $request->GetMarkets();
$data = json_decode($markets, true);
现在符合Array
,因此应该解决问题而无需采用任何变通方法。
此外,Swift现在允许类型自动合成Equatable
一致性,只要其所有成员都是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")
}
}
答案 1 :(得分:1)
这个问题非常糟糕,但仍未在Swift 4中修复。
除了ArrayResult
Result
来处理这个问题
public enum ArrayResult<T:Equatable> {
case success(result: [T])
case failure(error: Error)
}
extension ArrayResult: Equatable {
public static func ==(lhs: ArrayResult<T>, rhs: ArrayResult<T>) -> Bool {
switch (lhs) {
case .success(let lhsResult):
if case .success(let rhsResult) = rhs, lhsResult == rhsResult { return true }
case .failure(let lhsError):
// We cast associated Error to a NSError so we get Equatable behaviour
// (Apple guarantee that Error can always be bridged to an NSError)
if case .failure(let rhsError) = rhs, lhsError as NSError == rhsError as NSError { return true }
}
return false
}
}
func test() {
// Test 4: Check Result<[Post]> type for equality: NOW OK
let arrayResult1: ArrayResult<Post> = ArrayResult<Post>.success(result: arrayOfPosts1)
let arrayResult2: ArrayResult<Post> = ArrayResult<Post>.success(result: arrayOfPosts2)
if arrayResult1 == arrayResult2 {
print("equal results of array of posts")
}
}
答案 2 :(得分:-1)
load data;
没有扩展名