Natasha posted a article a little over a week ago: http://natashatherobot.com/swift-unused-optional-value/. I agree with her initial feelings, "This immediately stood out as "wrong" to me."
Basically she was talking about this:
var someOptionalVar: String? = "something there"
if someOptionalVar != nil {
// just need to check for the presence of a value
}
I don't like this. It just doesn't feel semantically correct. The optional is not nil
, it specifically has a value of None
. I've never liked this syntax; I've talked about it before – thankfully the bool
comparison has been lost, but the nil
check still sits wrong with me.
Another example:
let f‚ÇÄ: Bool? = true
let f‚ÇÅ: Bool? = false
let f‚ÇÇ: Bool? = nil
let fn = [ (f‚ÇÄ, "f‚ÇÄ"), (f‚ÇÅ, "f‚ÇÅ"), (f‚ÇÇ, "f‚ÇÇ")]
for (f, label) in fn {
if f == nil {
println("\(label) has no value")
}
if f != nil {
println("\(label) has a value")
}
if let fv = f {
println("\(label) = \(fv)")
}
else {
println("\(label) = nil")
}
switch (f) {
case .Some(_):
println("\(label) has a value.")
case .None:
println("\(label) has no value")
}
}
It's a bit annoying that we have so many ways to check for the presence of a value in an optional. I find languages that have multiple ways of achieving the same thing end up being confusing, especially as more features get added. It's unnecessary complexity that adds over time. Natasha already pointed out the multiple discussions of people doing it different ways.
I also prefer a different way:
func hasValue<T>(value: T?) -> Bool {
switch (value) {
case .Some(_): return true
case .None: return false
}
}
for (f, label) in fn {
if hasValue(f) {
println("\(label) has a value")
}
if !hasValue(f) {
println("\(label) has no value")
}
}
There is no ambiguity here, there is not transparent conversion between nil
and .None
, and most importantly to me, the code is always extremely obvious.