I read that the ternary operator ??
unwraps an optional if it is not nil, but if I do:
var type: String?
type = "milk"
let certainType = type ?? "melon"
then certainType will still be a String?
, and if I do
println("it's a \(certainType)")
it will print:
it's a Optional("milk")
Thoughts?
Update:
Sorry for the confusion - I meant var type: String?
I get that it should print "it's a milk", but what I saw in console is a "it's a Optional("milk")" - anyone else experienced the same issue? Could that be caused by string interpolation?
Asked by @Antonio, here is more context and real code and logging snapshot - type is from Note, which is a NSManagedObject class used to deal with xcdatamodel
class Note: NSManagedObject {
@NSManaged var type: String?
}
And I have the type set to 'todo' at some point, then have the following code to print them out:
println("type class:\(_stdlib_getDemangledTypeName(note.type))")
let type1 = note.type ?? "note"
println("type1:\(type1)")
let type2: String = note.type ?? "note"
println("type2:\(type2)")
And the output:
type class:Swift.Optional
type1:Optional("todo")
type2:todo
As you can see, if I don't explicitly mark the type1's type as String, it will print undesired result Optional("todo") - I use the type in a string interpolation to construct a path so it matters
The OP asserts that code similar to this:
var type: String? = "milk"
let certainType = type ?? "melon"
println("it's a \(certainType)")
prints an unexpected string:
"it's a Optional("milk")"
whereas it should be:
"it's a milk"
It turns out that happens when the variable is actually a property with the @NSManaged
attribute.
I suspect that there is a bug in type inference. The OP states that:
let certainType = type ?? "melon"
prints the wrong result, whereas:
let certainType: String = type ?? "melon"
prints the correct one.
So for some reason, without explicitly indicating the variable type, the nil coalescing operator is returning an optional.
If I change the type of the type
variable to either AnyObject
or AnyObject?
, it actually prints the unexpected result:
var type: AnyObject = "milk"
let certainType = type ?? "melon"
println("it's a \(certainType)")
"it's a Optional(milk)"
My guess is: because the @NSManaged
attribute is used, the property is inferred with the wrong type (AnyObject?
) when used, unless the correct type is explicitly indicated.
As to why that happens, no idea (besides thinking it's a bug)