37

In Swift 2.x I believe I could do:

let number = 1
let result = Bool(number)

print(result) // prints out: true

But since Swift 3 I've been unable to do this and it gives me the error:

Cannot invoke initialiser for type 'Bool' with an argument list of type '(Int)'

Currently I'm using an extension to convert an Int to a Bool but I was wondering if there isn't a build in option to do this.

Henny Lee
  • 2,970
  • 3
  • 20
  • 37
  • 1
    It's not entirely clear what "converting an int to a bool" even means. Historically, languages like C treat non-zero as `true`, and `0` as `false`, but that's just a consequence of the implementation details of encoding true vs false in memory. When you think about it, it actually makes little sense, semantically. So instead, just use explicitly `i != 0`, to be clear about precisely what you mean. Over-assuming its generalizability and naming it something like `boolValue` is ambiguous. For one, Bash/linux exit codes are the opposite. 0 is good/true, non-zero is bad/false. – Alexander Jan 15 '20 at 16:14

7 Answers7

63

No, there is and has never been an explicit built in option for conversion of Int to Bool, see the language reference for Bool for details.

There exists, still, however, an initializer by NSNumber. The difference is that implicit bridging between Swift numeric type and NSNumber has been removed in Swift 3 (which previously allowed what seemed to be explicit Bool by Int initialization). You could still access this by NSNumber initializer by explicitly performing the conversion from Int to NSNumber:

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

print(result) // true

As @Hamish writes in his comment below: if we leave the subject of initializers and just focus on the end result (instantiating a Bool instance given the value of an Int instance) we can simply make use of the != operator for Int values (specifically, the operator with signature func !=(lhs: Int, rhs: Int) -> Bool), a generalization easily achievable using the != operator approach:

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

print(result) // true

Much like you yourself as well as @JAL describes in his answer, you could construct your own Bool by Int initializer, but you might as well consider generalizing this for any type conforming to the 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
Community
  • 1
  • 1
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • 12
    Or without the obj-c bridge, `let result = number != 0` :) – Hamish Oct 15 '16 at 14:40
  • 1
    @Hamish when I say `let i = 1; let b = Bool(i as NSNumber)`, why am I now told by the compiler to use `init(truncating:)`? – matt Jun 16 '19 at 17:37
  • 1
    @matt That's a part of [SE-0170](https://github.com/apple/swift-evolution/blob/master/proposals/0170-nsnumber_bridge.md), by using `init(truncating:)` you're acknowledging that the conversion might be lossy as any non-zero number is mapped to `true` (and can't therefore be mapped back to the original number). This is complimented by the introduction of `init(exactly:)`, which will return `nil` if the number cannot be exactly represented, which for `Bool` is any number that isn't 0 or 1. – Hamish Jun 16 '19 at 18:04
  • @Hamish Thanks, just what I need to know! – matt Jun 16 '19 at 18:08
  • 2
    @Hamish Oh dear Swift where have you gone in my life, these kind of comment discussions want to bring me back to it! :) – dfrib Jun 17 '19 at 08:14
  • Although this is the accepted answer, it is now deprecated and [the above](https://stackoverflow.com/a/61528152/323941) should be noted. – lkahtz Jan 13 '22 at 02:41
33

Swift 4

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

Swift 3

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

Usage

let number = 2
print(number.boolValue)

let items = ["1"]
print(items.count.boolValue)
deadcoder0904
  • 7,232
  • 12
  • 66
  • 163
lingchen
  • 473
  • 1
  • 5
  • 11
  • How about: `var boolValue: Bool { return self != 0 }` – LoVo Jan 07 '18 at 09:29
  • 1
    Updated for Swift 4: `extension Int { var boolValue: Bool { return self != 0 } }` – John Rogers May 08 '18 at 04:28
  • I'd use `Bool?`. In my opinion, `-1.boolValue` as well as `2.boolValue` should return `nil`. – RyuX51 Oct 05 '18 at 11:31
  • @RyuX51 ```extension Optional where Wrapped == Int { var boolValue: Bool { return self?.boolValue ?? false } } ``` – lingchen Jan 04 '19 at 07:17
  • @lingchen I didn't mean an optional Int but I'd prefer `nil` if the Int is not 0 or 1. Like `extension Int { var boolValue: Bool? { switch self { case 0: return true case 1: return false default: return nil } } }` – RyuX51 Jan 04 '19 at 12:11
6

There is no Boolean initializer that takes an Int, only NSNumber. Previously, the Int was implicitly bridged to NSNumber through Foundation, but that was removed in Swift 3.

You can do something like:

let result = Bool(number as NSNumber)

Or, you can extend Bool and create a custom init that takes an Int:

extension Bool {    
    init(_ number: Int) {
        self.init(number as NSNumber)
    }
}
JAL
  • 41,701
  • 23
  • 172
  • 300
6

I'm using Xcode 9.0.1 and Swift 3.0.

let result = (number as NSNumber).boolValue

which is working very well for me.

arthankamal
  • 6,341
  • 4
  • 36
  • 51
5

Swift 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)
patel dhruval
  • 1,002
  • 10
  • 12
1
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
Alchi
  • 799
  • 9
  • 19
0

Swift 5 try this

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

or

extension Int32 {
    var boolValue: Bool {
        return Bool.init(truncating: NSNumber.init(value: self))
    }
}
Victor Choy
  • 4,006
  • 28
  • 35