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.