This article explains the warning "Expression implicitly coerced from 'String?' to 'Any'" in Swift and provides solutions to avoid it.
Abstract
The article discusses the warning "Expression implicitly coerced from 'String?' to 'Any'" in Swift, which can occur when an optional String is printed. The warning is generated because the compiler is losing type information when casting from an optional to Any. The article explains the warning in easy, short, and long versions, and provides three solutions to avoid it: providing a default value, force-unwrapping the value, and explicitly casting. The article also provides links to further resources for understanding the print function and the Any type in Swift.
Opinions
The article suggests that losing type information is not something that should be done lightly.
The article suggests that force-unwrapping can be dangerous if the String is nil.
The article suggests that explicitly casting can be a better solution than force-unwrapping or providing a default value.
The article suggests that warning messages should be removed from code whenever possible.
Expression implicitly coerced from ‘String?’ to ‘Any’- WHY SWIFT, WHY :(
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.
varstr: 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:
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 -
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 optionalString (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
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
Provide a default value
Equivalently we are giving a non-optionalString that would be printed if the optional String turned out to be nil.
So to apply this to the situation above:
varstr: String? = "This is an optional String"print (str ?? "This is an optional String")
wait. That’s a poor solution.
What if… can we…
varstr: 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.
varstr: 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!
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!
varstr: String? = "This is an optional String"print (stras 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)