Expression implicitly coerced from ‘String?’ to ‘Any’- WHY SWIFT, WHY :(

A common warning in Swift

Image for post
Image for post
Photo by Sarah Kilian on Unsplash

Error messages in Swift can be troublesome, particularly if you have a manager who demands that you remove any warnings from your code before committing to your repository.

This article will explain warning Expression implicitly coerced from ‘String?’ to ‘Any’ can be avoided but also how it occurs and why.

Difficulty: Beginner | Easy | Normal | Challenging

Terminology

Any: An instance of any type, including function types

Compiler: A program that converts instructions into a machine-code or lower-level form so that they can be read and executed by a computer

Optional: Swift introduced optionals that handle the absence of a value, simply by declaring if there is a value or not. An optional is a type on it’s own!

String: A collection of Characters

Type Casting: A way to either check the type of an instance, or treat the instance as a different superclass or subclass

Variadric parameters: A parameter for a function that accepts zero or more values of the specified type

The warning

There are a number of variations of this error, but we can take a (relatively) simple example where an optional String is printed.

var str: String? = "This is an optional String"
print (str)

this generates the warning “Expression implicitly coerced from “String?” to ‘Any’ as shown in the following screenshot:

Image for post
Image for post

What’s happening for this error message

The easy to understand version

The Compiler says: Please try to avoid losing type information

When implicity casting from an optional to Any you are losing the information that the String is potentially optional. Not cool man, not cool at all.

The short version

Swift forces the optional String to Any, and since an optional String can potentially be nil . This could be a disaster since losing information from a type is not something that should be done lightly, and it makes sense that the compiler needs to communicate this to you in the form of a warning message.

The long version

The print function has a Variadric parameters for the items that will be printed -

func print(_ items: Any, separator: String = "", terminator: String = "/n")

Now the more observant of you will see that the items are passed as type Any.

The warning that you are implicitly coercing can be thought of as forcing the optional String (String?) into the wider Any type — as any value type can be forced to behave asAny. Because the type conversion is not obvious to the programmer, there may be side-effects of which you are not fully aware.

That’s quite a mouthful, and there is much there to digest — and if you want the in depth explanations there are full guides on the Any type is HERE, and value types HERE.

However, we can see that we can cast any of the following types to Any

Image for post
Image for post

and we should remember that when implicitly coercing the type there may be non-obvious side effects, one of which in Swift can be that the code can crash. The code can crash because if the type cannot be forced into the Any type you could experience a runtime crash (because what did you expect the machine to do at that point).

The solution

Swift gives us three different options for solving this warning. Let us investigate each in turn

Image for post
Image for post

Provide a default value

Equivalently we are giving a non-optional String that would be printed if the optional String turned out to be nil.

So to apply this to the situation above:

var str: String? = "This is an optional String"
print (str ?? "This is an optional String")

wait. That’s a poor solution.

What if… can we…

var str: String? = "This is an optional String"
print (str ?? "This is an error")

although what would you expect the user to do if they were met with this error? It’s not a great solution in this particular case.

Force-unwrap the value to avoid this warning

Force-unwrapping often means that you are telling the compiler that you know what you’re doing.

var str: String? = "This is an optional String"
print (str!)

You are guarenteeing that there will not be a runtime crash.
Are you sure?

If the String is nil there will be an awful crash — can’t you see that hill? Pull up the yoke!

Image for post
Image for post

Explicitly cast

We can make the casting explicit. That is, we are taking responsibility for the casting process and telling the compiler we understand the side-effects that can happen because of this.

By choosing this option, we understand that we are losing the optional information and telling the compiler we are aware of that!

var str: String? = "This is an optional String"
print (str as Any)

Conclusion:

Warning messages are a fact of life, but it is correct to try to remove them from your code whenever possible.

This article tells you about how the print function in Swift works, how the compiler warns you about type casting and how this warning can be avoided.

Extend your knowledge

Apple have documentation for the print function (HERE)

There is a full guide on the Any type (HERE)

The Twitter contact:

Any questions? You can get in touch with me here

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store