Thanh Pham Thanh Pham - 6 months ago 51
Swift Question

Why can nil be returned from a non-optional function in this case?

I am trying the below code in Playground and I don't quite understand why the compiler doesn't give an error when

, which is
, is returned from a non-optional function; and why it does when essentially
is being compared to
and gives an error message which seems not correct when claiming that
can never be

is also
, why returning
directly as in
is not allowed?

func foo() -> Any {
let bar: String? = nil
return bar

let foobar = foo()

if foobar == nil {


func foo2() -> Any {
return nil

enter image description here


Let's explain exactly what happens in your code:

func foo() -> Any {
    let bar: String? = nil
    return bar

nil is a literal that gets converted to type String? (or Optional<String>), that is, into Optional<String>.None.

Then it is cast to Any. Anything can be cast to Any, including optionals. Basically you have decided to hide the underlining types.

Then foobar == nil. Note that == is an operation that is not automatically available for all types. The comparison with nil is defined on optional types, e.g. for Optional<T> with another Optional<T>.

In this case you have Any and a nil literal. Any itself is not an optional, therefore you cannot compare it directly with nil.

You can cast it to an optional Any.

let optionalFoobar = any as Any?

However, now the variable contains a double optional Optional<Any>.Some(Optional<String>.None) and comparison with nil won't work.

The only thing that would work would be:

if (foobar as Any?) as? String == nil {
    print("is nil")

In short, don't use Any and if you are using non-optional Any, don't store optional types into it, it will get really complicated and unusable in practice.