【问题标题】:Is there a difference between == true and != false in swift?== true 和 != false 之间有区别吗?
【发布时间】:2016-12-02 21:59:24
【问题描述】:

我的 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 还是只是随机字符。
  • 在这种情况下,在 Swift 中鼓励使用保护语句来检查 nil。此外,您可能需要研究 Equatable 协议以供将来参考。

标签: swift xcode if-statement boolean nsurl


【解决方案1】:

正如其他答案中已经解释的那样,比较可选 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 == truex == 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 的新手,感谢您打破这一点。
【解决方案2】:

在创建NSURL 时,您并不想检查布尔值,而是要确保您创建的NSURL 不为零。尝试将其包装在 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 语句可确保您创建的 NSURLNSData 对象是非零且有效的对象,然后您可以向它们添加 else 语句来处理您的 @ 987654327@ 或 data 对象为零。这将使您免于因使用 ! 运算符强制展开而导致的意外崩溃。

【讨论】:

  • 当我使用 if let data = try? NSData(contentsOfURL: url, options: []) as? NSData { 时,它说从 'NSData' 到 'NSData' 的条件转换总是成功。
  • 我从答案中删除了as? NSData。我从你的代码中复制了不必要的转换。
  • 这成功了!谢谢!!!现在我的 if 和 else 正在工作。感谢帮助!
【解决方案3】:

是的,对一些文档有不同的看法。在这个 init 方法中,它是错误的。

公共便利初始化?(string URLString: String)

问号表示它是错误的。

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

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

所以在一个具体的例子中,比如你的例子。你可以在操场上测试它

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//
}

【讨论】:

  • NSURL.init(string:) 返回NSURL 对象或nil。它不返回false
  • 这就是为什么说“以某种方式”帮助他们理解
  • “在某种程度上”在这里不适合。因为将NSURL?false 进行比较永远不能被视为“相等”。
  • 您应该注意NSURL(string: urlString) != false 始终为真,即使NSURL(string: urlString) 返回nil。事实上,它相当于NSURL(string: urlString) != NSNumber(bool: false)。给 urlString 一个无效的 url 进行测试。
  • 感谢您的解释!我是 Swift 新手,所以可能会很困惑。
【解决方案4】:

==运算符检查两边的值是否相等。例如:

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
}

!= 运算符检查两个值是否不相等。例如:

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.
}

【讨论】:

    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 2012-08-23
    • 2019-12-12
    • 1970-01-01
    • 2023-01-25
    • 2010-12-23
    • 2018-01-18
    相关资源
    最近更新 更多