Reputation: 2219
I am experiencing with protocols and challenged myself to write a code snippet that overloads the ==
operator so that it returns true
when I compare a random String
with value "42"
with a Int
of value 42
. Please don't question the usefulness by simply returning 42
on a String
, the main point is getting the Equality Operator
to run on the two different types.
Here is what I tried:
import Foundation
protocol IntTransformable: Equatable {
func toInt() -> Int
}
extension String: IntTransformable {
func toInt() -> Int {
return 42
}
}
extension Int: IntTransformable {
func toInt() -> Int {
return self
}
}
extension IntTransformable {
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.toInt() == rhs.toInt()
}
}
// throws: Ambiguous reference to operator function '=='
if "42" == 42 {
print("equal")
} else {
print("unequal")
}
import Foundation
protocol IntTransformable: Equatable {
func toInt() -> Int
}
extension String: IntTransformable {
func toInt() -> Int {
return 42
}
}
extension Int: IntTransformable {
func toInt() -> Int {
return self
}
}
extension IntTransformable {
// throws: Protocol 'IntTransformable' can only be used as a generic constraint because it has Self or associated type requirements
static func == (lhs: IntTransformable, rhs: IntTransformable) -> Bool {
return lhs.toInt() == rhs.toInt()
}
}
// throws: Ambiguous reference to operator function '=='
if "42" == 42 {
print("equal")
} else {
print("unequal")
}
Upvotes: 0
Views: 119
Reputation: 119168
You should use these two functions:
func ==(lhs: String, rhs: @autoclosure ()->Int) -> Bool {
guard let stringIntValue = Int(lhs) else { return false }
return stringIntValue == rhs()
}
func ==(lhs: Int, rhs: String) -> Bool {
guard let stringIntValue = Int(rhs) else { return false }
return lhs == stringIntValue
}
But if you really want to involve Protocol
s here, you should do this like:
extension IntTransformable {
static func ==<T: IntTransformable>(lhs: Self, rhs: T) -> Bool {
return lhs.toInt() == rhs.toInt()
}
}
Usage:
print( 42 == "42" )
print( "42" == 42 )
Upvotes: 3
Reputation: 534925
You're way overthinking this. There is no reason to use protocols here, and you really can't do it because protocols are not really types. Just write your operator(s) at top level:
func == (lhs: Int, rhs: String) -> Bool {
return lhs == Int(rhs)
}
func == (lhs: String, rhs: Int) -> Bool {
return Int(lhs) == rhs
}
Testing:
print(5 == "5") // true
Upvotes: 1
Reputation: 5
create a string extension, like
public string ToInt(this int value) { // some conversion code
return ConvertedStringValue; }
or you can use a uint.TryParse(string value, out uint output) this statement will return true if conversion is successful.
Upvotes: -3