在Swift中,== true和!= false之间有什么区别吗?

3

我在我的Swift应用程序中有这段代码

func parseJSON() {

    let urlString = "www.websitethatlinkstoJSONfile.com"

    if NSURL(string: urlString) == true {
        let url = NSURL(string: urlString)
        let data = try? NSData(contentsOfURL: url!, options: []) as NSData
        let json = NSData(data: data!)

//更多代码

然而,即使链接实际上有效且正确,if语句也永远不会被满足,它会跳过它并移动到else。所以我将代码改为:

if NSURL(string: urlString) != false 

它完美地工作了。不过我不确定原因是什么?


NSURL(string:)会对任何字符串返回true,无论它是有效的URL还是随机字符。 - Khundragpan
在Swift中,建议在像这样的情况下使用guard语句来检查nil。此外,您可能希望研究Equatable协议以供将来参考。 - Laurence Wingo
4个回答

3
如其他答案中已经解释的那样,将可选类型的NSURL?truefalse进行比较并不是您想要的,您应该使用可选绑定。
但是为什么它可以编译?结果如何解释呢?
NSURL(string: urlString) == true中,左侧的类型为NSURL?,而NSURLNSObject的子类。有一个==操作符接受两个可选操作数:
public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

编译器使用BoolNSNumber的隐式转换来进行编译。因此,您的代码等同于:
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'

注意:这是不要将布尔值与truefalse进行比较的另一个理由,即

 if a == true && b == false { ... }

更好的写法是

 if a && !b { ... }

适用于您的情况,您将会得到一个编译器错误提示问题:
let urlString = "http://www.websitethatlinkstoJSONfile.com"
if NSURL(string: urlString) {  }
// error: optional type '_' cannot be used as a boolean; test for '!= nil' instead

感谢您的精彩解释!我是Swift的新手,非常感谢您对此进行了详细的讲解。 - cheesydoritosandkale

1
你在创建NSURL时不需要检查布尔值,而是要确保你创建的NSURL不是nil。尝试使用if let语句将其包装起来,以确保你创建的任何URL都不是nil,然后再执行进一步的代码。
   let urlString = "www.websitethatlinkstoJSONfile.com"

    if let url = NSURL(string: urlString) {
       if let data = try? NSData(contentsOfURL: url, options: []) {
           let json = NSData(data: data)
       } else { 
          //Handle case where data is nil
       }
    } else { 
        //Handle case where url is nil 
    }

使用if let语句可以确保创建的NSURL和NSData对象是非空且有效的对象,然后您可以添加else语句来处理url或data对象为nil的情况。这将避免由于强制解包操作符"!"而导致意外崩溃。请注意保留HTML标签。

当我使用if let data = try? NSData(contentsOfURL: url, options: []) as? NSData {时,它会显示条件转换从“NSData”到“NSData”总是成功。 - cheesydoritosandkale
我从答案中删除了as?NSData。这是我从你的代码中复制来的不必要的强制转换。 - NSGangster
这个可行!谢谢!!现在我的if和else都能工作了。感谢您的帮助!! - cheesydoritosandkale

1

是的,这里有一个不同的方法,请查看一些文档。在这个 init 方法中它是可失败的。

public convenience init?(string URLString: String)

问号表示它是可失败的。

所以它将返回一个 NSURL 对象或者 nil。

convenience init?(parameter: AnyObject) {
    if parameter == nil {
        return nil
    }
    self.init()
}

所以就像你的例子一样,你可以在 playground 中进行测试。

let urlString = "100"

if NSURL(string: urlString) == true {
    print("true")
    //Never prints in any circumstance//
}


if NSURL(string: urlString) != false {
    print("true")
    //always prints//
}

if NSURL(string: urlString) != nil {
    print("true")
   //object was created//
}

3
NSURL.init(string:) 返回 NSURL 对象或 nil,而不是返回 false - OOPer
这就是为什么说“在某种程度上”,以帮助他们理解。 - Asdrubal
2
请注意,即使NSURL(string: urlString)返回nilNSURL(string: urlString) != false始终为真。实际上,它相当于NSURL(string: urlString) != NSNumber(bool: false)。请使用无效的url测试urlString - OOPer
谢谢您的解释!我是Swift的新手,所以可能会非常困惑。 - cheesydoritosandkale
@cheesydoritosandkale https://dev59.com/7V8d5IYBdhLWcg3wiip9 - Asdrubal
显示剩余3条评论

1
< p > == 运算符检查两侧的值是否相等。例如:

var data:Int = 6
if data == 5 {
   //if this block is executed that means `data` is exactly equal to 5
   //do something
}
else {
    //In this situation, this block of code will be executed.
   //if this block is executed that means data is anything other than 5.
   //do something
}
< p > < code >!= 运算符检查两个值是否不相等。例如:
var data:Int = 6
if data != 5 {
    //In this situation, this block of code will be executed.
   //If this block is executed that means `data` is anything other than 5.
   //do something
}
else {
   //if this block is executed that means data is exactly equal to 5.
   //do something
}

在您的代码中,if NSURL(string: urlString) == true 检查 NSURL(string: urlString) 是否返回 true,如果是,则执行 if 块,否则执行 else 块。 NSURL(string: urlString) 是一个便利初始化器,它创建并返回 NSURL 对象。如果无法创建,则会返回 nil
无论如何,它都不会返回 truefalse。因此,当您将其与 true 进行比较时,它总是失败并进入 else 块。
当您检查它是否不等于 false (!= false) 时,它变为 true,因为 NSURL(string: urlString) 返回 NSURL 对象,而这个对象不等于 false。
因此,如果您想检查是否创建了 NSURL 对象,可以检查返回值是否为 nil
if NSURL(string: urlString) != nil {
   //Object is created successfully.Now you can do whatever you want this object.
}
else {
   //It failed to create an object.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接