Search code examples
swiftstride

swift 3 stride cannot invoke


var arr: [Double] = Array(stride(from: 0, through: 11, by: 1.0))

This code is ok, but if I write this, "cannot invoke" problem appears

var s = 11
var arr: [Double] = Array(stride(from: 0, through: s, by: 1.0))

Solution

  • In order for your stride statement to produce Double, the values passed to from, through and by must be Doubles.

    In the first case, Swift infers the literals 0 and 11 to be Doubles since 1.0 is a Double and that is the only way they can match. This works because Double conforms to the ExpressibleByIntegerLiteral protocol which just means that you can initialize a Double with an integer literal and an integer literal can be inferred to be a Double if necessary.

    In the second case, you have assigned 11 to s and Swift assigns s the type Int. So when you try to use that in the stride statement, the types don't match.

    You can fix this in a number of ways:

    1. Declare s to be a Double with var s: Double = 11. In this case, you've explicitly assigned the type of s, so Swift uses the ExpressibleByIntegerLiteral conformance of Double to initialize s.
    2. Declare that 11 is a Double with var s = 11 as Double. Here you have told Swift that 11 is a Double which works because Double conforms to ExpressibleByIntegerLiteral. Swift then infers the type of s to also be Double.
    3. Convert 11 to a Double with var s = Double(11). This uses an initializer of Double that takes an Int as input. Swift then infers the type of s to be Double from the value assigned to it.
    4. Convert s when you use it with Double(s). Here you are explicitly using the Double initializer to create a Double with the Int s.
    5. Declare s with a Double literal with var s = 11.0. Here, Swift infers the literal 11.0 to be of type Double and then infers the type of s to also be a Double since it is initialized by a Double.