【发布时间】:2021-04-29 20:24:22
【问题描述】:
我正在尝试扩展Array.contains 函数以允许可选参数并在参数为零时返回false。我从这个开始:
extension Array {
func contains(_ element: Element?) -> Bool {
if let element = element {
return self.contains(element)
} else {
return false
}
}
}
当参数为 nil 时,调用代码会正确找到我的函数版本。但是,此函数中的self.contains 不会调用原始版本——它会调用自身并创建一个无限循环。有没有办法让self.contains 行调用原函数?
接下来,我尝试用不同的实现替换self.contains,但我想不出任何不需要将扩展限制为Element: Equatable,就像这样:
extension Array where Element: Equatable {
func contains(_ element: Element?) -> Bool {
if let element = element {
return (self.firstIindex(of: element) != nil)
} else {
return false
}
}
}
但是,这使得该功能无法用于 UIButton、Dictionary 和其他我需要使用它的元素类型。原始的contains 函数如何为这些类型执行此操作? (我搜索了一下,没找到它的源代码。)
接下来,我删除了约束并更改了方法签名以消除我的扩展函数和原始函数之间的歧义:
extension Array {
func contains(optional element: Element?) -> Bool {
if let element = optional {
return self.contains(element)
} else {
return false
}
}
}
但是当我更改方法签名时,编译器错误告诉我self.contains 行现在要求 Element 符合 Equatable。
原始函数如何免除此限制,而签名略有不同的函数需要它?
我觉得这应该是微不足道的,但我已经花了几个小时,但找不到有效的设置。有人可以给我一个解决方案吗?
【问题讨论】:
-
"原函数如何不受此限制?"不是……见documentation。注意措辞:“当 Element 符合 Equatable 时可用。”
-
另请注意:
UIButton和Dictionary都符合Equatable。
标签: swift types collections protocols extension-methods