【问题标题】:Converting Int to Bool将 Int 转换为 Bool
【发布时间】:2017-02-24 21:15:03
【问题描述】:

在 Swift 2.x 中我相信我可以做到:

let number = 1
let result = Bool(number)

print(result) // prints out: true

但自从 Swift 3 以来,我一直无法做到这一点,它给了我错误:

无法使用参数列表为“Bool”类型调用初始化程序 输入“(整数)”

目前我正在使用扩展程序将 Int 转换为 Bool 但我想知道是否没有内置选项来执行此操作。

【问题讨论】:

  • “将 int 转换为 bool”甚至意味着什么并不完全清楚。从历史上看,像 C 这样的语言将非零视为true,将0 视为false,但这只是在内存中编码真与假的实现细节的结果。当您考虑它时,从语义上讲,它实际上没有什么意义。因此,只需明确使用i != 0,以明确您的意思。过度假设它的普遍性并将其命名为boolValue 是模棱两可的。一方面,Bash/linux 退出代码是相反的。 0 是好/真,非零是坏/假。

标签: swift int boolean swift3


【解决方案1】:

不,存在并且从未有将Int 转换为Bool 的显式内置选项,请参阅the language reference for Bool for details

但是,initializer by NSNumber 仍然存在。不同之处在于 Swift 数字类型和 NSNumber 之间的隐式桥接已在 Swift 3 中删除(以前允许 Int 初始化似乎是显式的 Bool)。您仍然可以通过NSNumber 初始化程序通过显式执行从IntNSNumber 的转换来访问它:

let number = 1
let result = Bool(number as NSNumber)

print(result) // true

正如@Hamish 在下面的评论中所写:如果我们离开初始化器的主题而只关注最终结果(实例化一个Bool 实例,给定Int 实例的值),我们可以简单地使用!= 运算符用于Int 值(特别是带有签名func !=(lhs: Int, rhs: Int) -> Bool 的运算符),使用!= 运算符方法可以轻松实现泛化:

let number = -1
let result = number != 0

print(result) // true

就像您自己以及 @JAL describes in his answer 一样,您可以通过 Int 初始化器构造自己的 Bool,但您不妨考虑将其推广到符合 Integer protocol 的任何类型:

extension Bool {
    init<T: Integer>(_ num: T) {
        self.init(num != 0)
    }
}

/* example usage */
let num1: Int8 = -1
let num2: Int = 3
let num3: UInt64 = 0
// ....
let result1 = Bool(num1) // true
let result2 = Bool(num2) // true
let result3 = Bool(num3) // false

【讨论】:

  • 或者没有 obj-c 桥,let result = number != 0 :)
  • @Hamish 当我说let i = 1; let b = Bool(i as NSNumber) 时,为什么编译器现在告诉我使用init(truncating:)
  • @matt 这是SE-0170 的一部分,通过使用init(truncating:),您承认转换可能是有损的,因为任何非零数字都映射到true(并且不能因此被映射回原始数字)。 init(exactly:) 的引入对此进行了补充,如果数字不能准确表示,它将返回 nil,对于 Bool,它是任何非 0 或 1 的数字。
  • @Hamish 谢谢,正是我需要知道的!
  • @Hamish 哦,亲爱的斯威夫特,你在我的生活中去了哪里,这些评论讨论想让我回到过去! :)
【解决方案2】:

斯威夫特 4

extension Int {
    var boolValue: Bool { return self != 0 }
}

斯威夫特 3

extension Integer {
    var boolValue: Bool { return self != 0 }
}

用法

let number = 2
print(number.boolValue)

let items = ["1"]
print(items.count.boolValue)

【讨论】:

  • 怎么样:var boolValue: Bool { return self != 0 }
  • 为 Swift 4 更新:extension Int { var boolValue: Bool { return self != 0 } }
  • 我会使用Bool?。在我看来,-1.boolValue2.boolValue 应该返回 nil
  • @RyuX51 extension Optional where Wrapped == Int { var boolValue: Bool { return self?.boolValue ?? false } }
  • @lingchen 我的意思不是可选的 Int,但如果 Int 不是 0 或 1,我更喜欢 nil。就像 extension Int { var boolValue: Bool? { switch self { case 0: return true case 1: return false default: return nil } } }
【解决方案3】:

没有采用Int 的布尔初始化程序,只有NSNumber。以前,Int 通过 Foundation 隐式桥接到 NSNumber,但在 Swift 3 中已删除。

你可以这样做:

let result = Bool(number as NSNumber)

或者,您可以扩展 Bool 并创建一个采用 Int 的自定义 init:

extension Bool {    
    init(_ number: Int) {
        self.init(number as NSNumber)
    }
}

【讨论】:

  • 有趣的是,这似乎不适用于 Xcode 8.0,但适用于 8.2/8.3。
  • @BonanzaDriver 什么“不起作用”?它不编译吗?没有返回正确的布尔值?
【解决方案4】:

我正在使用 Xcode 9.0.1 和 Swift 3.0。

let result = (number as NSNumber).boolValue

这对我来说效果很好。

【讨论】:

    【解决方案5】:

    斯威夫特 5

    let number = 1
    let result = Bool(truncating: number as NSNumber) //here result will be false if the number's value is 0 and it will be true for any other number's value
    
    print(result)
    

    【讨论】:

      【解决方案6】:
      let iFalse: Int = 0
      let iTrue: Int = 1
      let iNil: Int = 2 //or any number other than 0 & 1
      
      Bool(exactly: iFalse as NSNumber) //false
      Bool(exactly: iTrue as NSNumber) //true
      Bool(exactly: iNil as NSNumber) //nil
      

      【讨论】:

        【解决方案7】:

        Swift 5试试这个

        extension Int32 {
            var boolValue: Bool {
                return (self as NSNumber).boolValue
            }
        }
        

        extension Int32 {
            var boolValue: Bool {
                return Bool.init(truncating: NSNumber.init(value: self))
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-01
          • 2014-09-19
          • 2011-09-28
          • 1970-01-01
          • 2016-11-29
          • 2012-01-14
          • 1970-01-01
          • 2015-10-07
          相关资源
          最近更新 更多