I am facing a problem where the object which I have created is a non-optional value but somehow it is getting converted into an optional one.
I have tried in the playground also refer to the screenshot below. Does anyone know what am I missing?
I am facing a problem where the object which I have created is a non-optional value but somehow it is getting converted into an optional one.
I have tried in the playground also refer to the screenshot below. Does anyone know what am I missing?
Simply remove the implicitly unwrapped optional sign !
. Do the class like this:
import UIKit
class SomeDataModelClass {
var someProperty: String
init(someProperty: String) {
self.someProperty = someProperty
}
}
let someObject = SomeDataModelClass(someProperty: "Non Optional String")
print(someObject.someProperty)
And you won't get the previous result.
Implicitly unwrapped optionals (any type suffixed with a !
) are optionals, underneath the surface. This recently changed in Swift 4+. Here is an excerpt from the Swift.org blog Reimplementation of Implicitly Unwrapped Optionals (with emphasis added):
Implicitly unwrapped optionals are optionals that are automatically unwrapped if needed for an expression to compile. To declare an optional that’s implicitly unwrapped, place a
!
after the type name rather than a?
.A mental model many people have for implicitly unwrapped optionals is that they are a type, distinct from regular optionals. In Swift 3, that was exactly how they worked: declarations like
var a: Int?
would result ina
having typeOptional<Int>
, and declarations likevar b: String!
would result inb
having typeImplicitlyUnwrappedOptional<String>
.The new mental model for IUOs is one where you consider
!
to be a synonym for?
with the addition that it adds a flag on the declaration letting the compiler know that the declared value can be implicitly unwrapped.
In your case, specifically, you are printing an implicitly unwrapped optional, which is really just a fancy optional, so it’s expected & correct behavior. If you want to print the string value itself, you’ll need to explicitly unwrap the value, print(someObject.someProperty!)
. The linked blog post deep dives into the new reimplementation of IUOs & is worth a skim.
Implicitly unwrapped optional is still optional. It just doesn’t look like that when you’re writing your code. So this property still can hold no value.
But for your specific need there is no reason to having implicitly unwrapped optional. Make it either non-optional or optional. Also you can use struct
instead of class and then you can use default memberwise intializer
struct Model {
var property: String
}
let object = Model(property: "text")
print(object.property)
text