Swift 强制对象实现可与协议进行比较协议只能用作通用约束
我有一个对象数组。现在我想强制这些对象实现可比性 所以我创建了这样一个协议:Swift 强制对象实现可与协议进行比较协议只能用作通用约束,swift,Swift,我有一个对象数组。现在我想强制这些对象实现可比性 所以我创建了这样一个协议: protocol Foo: Comparable { } 除了创建阵列外,一切都很顺利: let array: [Foo] = [obj1, ..] 然后,编译器突然抱怨: 协议“Foo”只能用作一般约束,因为它具有自身或关联的类型要求 还有别的办法吗 编辑 class View: UIView { let viewModel: SomeViewModel } class SomeViewModel {
protocol Foo: Comparable { }
除了创建阵列外,一切都很顺利:
let array: [Foo] = [obj1, ..]
然后,编译器突然抱怨:
协议“Foo”只能用作一般约束,因为它具有自身或关联的类型要求
还有别的办法吗
编辑
class View: UIView {
let viewModel: SomeViewModel
}
class SomeViewModel {
let views: [UIView]
}
通常,当人们添加此一致性时,他们会尝试执行排序a[Foo]
或查找最小值之类的操作,但即使您可以创建此数组,这也行不通,因为Compariable要求一个类型与其自己的类型相比较,而不是与其他匹配协议的类型相比较。因此,例如,给定您的数组
,您不能使用array.min()
来查找最小元素,因为Comparable不要求Foo与Foo可比,只要求符合Foo的事物可以与自身相比较
相反,您需要扩展协议,以要求一致性类型能够将自己与任何Foo进行比较:
考虑到这些,您可以构造您需要的任何其他算法。您不能使用默认形式的contains
或sorted
,但可以在where
和by
参数中使用这些函数
通过提供一些默认实现,您还可以使这一点变得更好:
extension Foo where Self: Equatable {
func isEqual(to other: Foo) -> Bool {
guard let other = other as? Self else {
return false
}
return self == other
}
}
同样,对于isLessThan
如果您希望包含,如果方便的话,还可以提供帮助:
extension Sequence where Element == Foo {
func contains(_ element: Element) -> Bool {
return contains(where: { $0.isEqual(to: element) })
}
}
如果您想要此讨论的更长版本,请参阅。这个特定主题在37:40出现。obj1是什么类型的?obj1是一个扩展UIView的类。UIView有一个viewModel,我想从该viewModel中使用一个属性对数组进行排序。也许我觉得它太复杂了。在这里添加代码。错误基本上意味着像“一个Foo
对象数组”这样的语句,就像“一个可比较的对象数组”一样,是没有意义的,因为有一种类型符合可比较的
(比如,日期
)可能与符合compariable
(例如,String
)的另一种类型完全不同。当您有一个关联类型的协议或一个引用Self
的协议时,就会发生这种情况。相反,创建一个[View]
数组,并扩展视图
以符合可比性
,我想你在问一个问题。通过比较观点,根据您实际想要达到的目标重申问题
extension Sequence where Element == Foo {
func contains(_ element: Element) -> Bool {
return contains(where: { $0.isEqual(to: element) })
}
}