Reputation: 7826
I am converting my code from Objective-C to Swift. I declared a function to compare values of two properties and return a Bool
.
And I am confused about why this code not work in Swift.
private var currentLineRange: NSRange?
var location: UInt?
func atBeginningOfLine() -> Bool {
return self.location! == self.currentLineRange?.location ? true : false
}
Compiler gave me an error:
Could not find an overload for == that accepts the supplied arguments
Thanks.
Upvotes: 1
Views: 3215
Reputation: 40965
You have two optional values and you want to check if they’re equal. There is a version of ==
for comparing two optionals – but they need to be of the same type.
The main problem here is that you are comparing NSRange.location
, which is a Int
, with location
, which is a UInt
. If you tried to do this even without the complication of the optionals, you’d get an error:
let ui: UInt = 1
let i: Int = 1
// error: binary operator '==' cannot be applied to operands of
// type 'Int' and ‘UInt'
i == ui
There’s two ways you can go. Either change location
to be an Int
, and you’ll be able to use the optional ==
:
private var currentLineRange: NSRange?
var location: Int?
func atBeginningOfLine() -> Bool {
// both optionals contain Int, so you can use == on them:
return location == currentLineRange?.location
}
Or, if location
really does need to be a UInt
for some other reason, map
one of the optionals to the type of the other to compare them:
private var currentLineRange: NSRange?
var location: UInt?
func atBeginningOfLine() -> Bool {
return location.map { Int($0) } == currentLineRange?.location
}
One thing to be careful of – nil
is equal to nil
. So if you don’t want this (depends on the logic you’re going for), you need to code for it explicitly:
func atBeginningOfLine() -> Bool {
if let location = location, currentLineRange = currentLineRange {
// assuming you want to stick with the UInt
return Int(location) == currentLineRange.location
}
return false // if either or both are nil
}
Upvotes: 1
Reputation: 11733
Swift has operator overloading, so == is a function. You have to define a function that takes your two types.
If you remove the UInt it works:
class Document {
private var currentLineRange: NSRange?
var location: Int?
func atBeginningOfLine() -> Bool {
if let currentLocation = self.location, lineRange = self.currentLineRange {
return currentLocation=lineRange?.location
} else {
return false
}
}
}
Modified to be null safe.
Upvotes: 1