Well in Any we can wrap any . But why we can't assign nil in Any directly, but we can indirectly in this way.
var a: Any
a = nil // Nil cannot be assigned to type 'Any'
var z: Int? = 0
a = z
z = nil
a = z // a is nil
Why we have regular Any and optional 'Any?' . Why we can't use regular any instead of optional any everywhere? I will be grateful for articles about this topic.
nil is syntactic sugar for Optional<T>.none. Compiler doesn't know what is T on the second line of your example. For example it could be Int? or String? or something else.
Yes. So the Any behavior forces to define every optional type as var z: Optional<Int> = 0. I understand that Swift has not nil at all. But the Any? case broke this clarity concept a little bit.
nil is a literal & only a type that conforms to ExpressibleByNilLiteral can be initialised with nil and since Any does not conform to that protocol, it cannot be initialised with nil. The only type that does is Optional. So, you can either do:
let a: Any? = Optional.none // Any? is sugar for Optional<Any>
let a: Any? = nil // Any? is sugar for Optional<Any>
or
let a: Optional<Any> = .none
let a: Optional<Any> = nil
The value of x is nil (or Optional<Int>.none) however the type is Any. This is because the value (Int? or Optional<Int>.none) is getting type-erased to Any. The reason why the value is nil (or Optional<Int>.none) is because of the initial coercion of nil to Int?, so you get Optional<Int>.none.
That looks like a bug, and I have created a thread here to discuss it.
My understanding and expectation is that it should be possible to cast an Any back to the type it wraps, so I am glad you called attention to the fact that it is not currently possible when that type is Optional.
I think is not bug, I think is kind of bad practice. But in my work I meet casting from Any? all time :( And I do not understand why the compiler warning disappear when we print optional value like
print("(myOptioanal as Any)")
The warning is only there to stop people from accidentally printing things like “Optional(42)” when they meant to print just the number. Print takes a variable number of Any arguments, so manually casting to Any just tells the compiler that, yes, you really wanted to print the Optional.
Every type in Swift implicitly is a subtype of Any. Any can be anything, it does not imply that the type behind Any is an Optional, therefore assigning nil to it does not make much sense. You can take any type instance and up-cast it to Any, or in other words erase all the type information you had to nothing.