【发布时间】:2020-01-21 18:00:33
【问题描述】:
我正在体验协议并挑战自己编写一个代码 sn-p 重载 == 运算符,以便当我将随机 String 与值 "42" 与 Int 进行比较时,它 returns true值42。请不要通过简单地在 String 上返回 42 来质疑其有用性,重点是让 Equality Operator 在两种不同的类型上运行。
这是我尝试过的:
版本 1
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")
}
版本 2
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")
}
【问题讨论】:
-
您可以像
static func == (lhs: Self, rhs: Self) -> Bool { return lhs.toInt() == rhs.toInt() }一样简单地使您的协议工作,但是,在String和Int上使用运算符仍然会导致相同的错误。 -
你不能使用协议来做到这一点,因为协议并不是真正的类型。
-
@DávidPásztor 感谢代码改进提示。
-
@matt 如果我不能使用协议,我能做些什么呢?
-
顺便说一句,如果你想为类型
T引入不同的相等概念,我建议你制作一个包装T的struct,并通过实现新的平等的定义。在现有类型上定义==通常会导致这种歧义/混乱