Sander Saelmans
Sander Saelmans

Reputation: 861

Unexpected nil when initialising Integer with Double

I'm trying to understand what's happening in the following scenarios:

let input: [Double] = [2.3]
// scenario 1
input.compactMap { Int.init($0) } // [2]
// scenario 2
input.compactMap(Int.init) // []

Scenario 1 gives an array containing 2, as expected. The Double is rounded, and converted to an Int. Scenario 2 however gives an empty array, as the given Double is apparently not convertible to an Int.

Can someone explain what's happening here? I'd expected both scenarios to give the same output.

Upvotes: 1

Views: 47

Answers (1)

Sander Saelmans
Sander Saelmans

Reputation: 861

I found the answer by inspecting the different .init methods.

In scenario 1 the following initialiser is used:

init(_ source: Double)

whilst in scenario 2 this initialiser is used:

init?(exactly source: Double)

My expectation was that the same initialiser would be used here, as I've given no label to indicate that I'm referring to another initialiser. I guess this + the combination of using a compactMap makes swift prefer the initialiser used in scenario 2, as using a normal map instead of a compactMap produces the expected result.

The fix for now is to explicitly state that I want to use the initialiser from scenario 1:

input.compactMap(Int.init(_:)) // [2]

Upvotes: 4

Related Questions