Reputation: 11247
I received a compilation error from Xcode yesterday, saying
Binary operator '&&' cannot be applied to two Bool operands [1]
on
if text != nil && presentingViewController != nil {
...
}
text
is defined earlier as
var text: String = "" {
didSet {
...
}
}
and presentingViewController
is from UIViewController
, which is the super
class.
A friend of mine told me that it was caused by text
, which was of String!
, and the issue was solved by changing
var text: String
to
var text: String?
However, it still puzzles me why my explicitly defined String
becomes String!
. Can anyone provide any detail on this implicit conversion?
[1] This compilation error does not make sense, and this question is not a duplicate of another question of the same compilation error.
Upvotes: 0
Views: 853
Reputation: 1130
Your problem is related to what is called "optionals" in swift.
In Objective-C you could have a reference to NSString and it could either be pointing to an NSString instance - or to nil. In swift this is different!
A "regular" String in swift can never be nil. Only an "optional" String can be nil. This is how it would look in swift code:
var myRegularString : String // this can never be nil, can't compare to nil
var myOptionalString : String? // this can be nil (note the ?)
You have a "regular" String. So the compiler complains when you try to compare it to nil.
Optionals are explained here: Swift Programming Language/Basics/Optionals
Upvotes: 2
Reputation: 52538
Your friend most certainly didn't solve your problem, he just glossed over it.
You declared an instance variable of type String. text will always be a String. It can never, ever be nil. Asking "text != nil" is pointless because it cannot be nil. It doesn't even compile, because a String, always being nil, cannot even checked for being nil.
Your friend suggested to use String? or String!. That's in your situation total nonsense. You have text which is guaranteed to be always a String. Instead you change it to text which may be a String or nil. This doesn't help you in any way. Yes, now you can ask it whether it is nil. Before, you didn't even have to ask.
Upvotes: 1
Reputation: 6726
Your explicitly defined String
is not String!
is ... String
. Simple like that ;-)
String!
is an implicitly unwrapped Optional<String>
String?
is an Optional<String>
Optional<T>
means that it can be a value of type T
or Nothing
(and nothing can be compared to nil
).
Thus when you declare:
var text = ""
you declare an actual String and it cannot be nil
. That's why the compiler is complaining: a String cannot be Nothing
. Think of it as comparing a String
with a CGFloat
... the compiler will complain.
Since String!
is an Optional<String>
than it can be compared against nil
.
The !
simply is you declaring that you are absolutely sure it is not Nothing
such that you can use text
without unwrapping its actual value.
BTW, do not confuse and empty String (i.e.: ""
) with Nothing
.
var text = ""
is an actual String
just empty and it is not comparable with Nothing
Hope this helps.
Upvotes: 2