Swift:检查编译器是否支持条件一致性

时间:2018-04-23 12:18:16

标签: swift xcode

使用XCode 9.3,swift编译器引入了条件一致性,允许我们比较两个选项。

我们正在开发一个用于支持Swift 3.2和Swift 4.0的库,我们必须为字典定义以下比较器:

fileprivate func ==(lhs:[String: NSObject]?, rhs: [String:NSObject]?) -> Bool {
    var match = true
    if let lhs = lhs {
        if let rhs = rhs {
            match = lhs == rhs
        } else {
            match = false
       }
    }
    return match
}

在Swift 3.3和Swift 4.1中,这个比较器不再有效,并在行上产生无限循环

match = lhs == rhs

匹配器现在自称。 它是一个库,所以我们不能强迫我们的客户使用最新的XCode版本。

有没有办法检查编译器是否支持条件一致性?

1 个答案:

答案 0 :(得分:1)

较新的Swift版本为字典和选项提供了内置==运算符,并且还为可选类型提供了非可选类型的强制(请参阅下面的备注)。

因此,我认为最简单的版本是在新的Swift版本中简单地踢出整个==函数:

#if !swift(>=3.3)  // check the correct version, I'm not sure about 3.3 or newer
func ==(lhs:[String:Int]?, rhs: [String:Int]?) -> Bool  {
    print ("check same \(lhs) == \(rhs)")
    var match = true
    if let lhs = lhs {
        if let rhs = rhs {
            match = lhs == rhs
        } else {
            match = false
        }
    }
    return match
}
#endif


var a:[String:NSObject]? = ["a":"c" as NSObject]
var b:[String:NSObject]? = ["a":"c" as NSString]

print (a == b)

说明:

问题是在当前的Swift版本中,期望Optional的函数也可以被相应的非可选参数调用,如下所示:

func consumesOptional(value: Int?) -> Int {
    print ("consuming \(String(describing: value))")
    return value!
}

let x: Int = 1
let y = consumesOptional(value: x)
print(y)    // "consuming Optional(1)"

因此,如果您创建一个func ==来获取可选参数,然后(在if let级联调用==中使用非可选类型,这将导致递归,正确在下面的评论中说明。

有关详细信息,请参阅SE-0121