如其他答案中已经解释的那样,将可选类型的
NSURL?
与
true
或
false
进行比较并不是您想要的,您应该使用可选绑定。
但是为什么它可以编译?结果如何解释呢?
在
NSURL(string: urlString) == true
中,左侧的类型为
NSURL?
,而
NSURL
是
NSObject
的子类。有一个
==
操作符接受两个可选操作数:
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
编译器使用
Bool
到
NSNumber
的隐式转换来进行编译。因此,您的代码等同于:
if NSURL(string: urlString) == NSNumber(bool: true)
并且这将永远是错误的,以及
if NSURL(string: urlString) != NSNumber(bool: false)
这个语句将始终为真,因为左侧不是一个数字。
下面是一个示例:
func foo(x: NSObject?) {
print(x == true, x == false)
}
foo(NSNumber(bool: true)) // true, false
foo(NSNumber(bool: false)) // false, true
foo(NSObject()) // false, false !!!
最后一种情况是你所观察到的:无论是
x == true
还是
x == false
都会返回
false
。
对于未继承自
NSObject
的类,它不会编译通过:
class A { }
let a: A? = A()
if a == true { } // cannot convert value of type 'A?' to expected argument type 'Bool'
注意:这是不要将布尔值与true
或false
进行比较的另一个理由,即
if a == true && b == false { ... }
更好的写法是
if a && !b { ... }
适用于您的情况,您将会得到一个编译器错误提示问题:
let urlString = "http://www.websitethatlinkstoJSONfile.com"
if NSURL(string: urlString) { }
NSURL(string:)
会对任何字符串返回true,无论它是有效的URL还是随机字符。 - Khundragpan