Swift declaring array of multiple optional type to Any not work as expected

130 views Asked by At

I used Any type to store array of multiple optional type with default value, and got unexpected result.

let i64: Int64? = nil

print([
    i64 ?? 0,
    i64 ?? 0,
    i64 ?? 0
])

Then, [Optional(0), 0, 0] is printed.

Following is my detailed experiment. First, I declared the following variables:

let i64: Int64? = nil
let i32: Int32? = nil
let i: Int? = nil
let str: String? = nil

Then I put some of these variables into an Array and assigned to Any type.

var any: Any

any = [
    i64 ?? 0,
    i64 ?? 0,
    i64 ?? 0
]
print(any)                    // [0, Optional(0), 0]
print(type(of: any))          // Array<Any>

It's weird that one of the value is Optional(0) and others retained 0. And the position of that optional variable are not always located at the same index, it's placed randomly.

This situation occurred only if size of array is 3 or greater, array with 2 elements worked as expected.

any = [
    i64 ?? 0,
    i64 ?? 0
]
print(any)                    // [0, 0]
print(type(of: any))          // Array<Int64>

any = [
    i64 ?? 0,
    str ?? ""
]
print(any)                    // [0, ""]
print(type(of: any))          // Array<Any>

And I found that if I specified the type of those default value, it seems worked perfectly.

any = [
    i64 ?? Int64(0),
    i64 ?? Int64(0),
    i64 ?? Int64(0)
]
print(any)                    // [0, 0, 0]
print(type(of: any))          // Array<Int64>

any = [
    i64 ?? Int64(0),
    i64 ?? Int64(0),
    i64 ?? Int64(0),
    str ?? ""
]
print(any)                    // [0, 0, 0, ""]
print(type(of: any))          // Array<Any>

However, I couldn't conclude with a good explanation why this can work.

In my opinion, i64 ?? 0 should always considered 0 as same type of i64, which is Int64. It comes from the following assignment test:

let test1 = i64 ?? 0
print(type(of: test1))        // Int64
let test2 = i64 ?? Int64(0)
print(type(of: test2))        // Int64
let test3 = i64 ?? Int32(0)   // compiled error

But why i64 ?? 0 value in Array act different to i64 ?? Int64(0)?

Should I really need to specify the type of 0 in every assign operation? Is any way to make the array works as expected without the Int64(0) type conversion.

0

There are 0 answers