Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 强制对象实现可与协议进行比较协议只能用作通用约束_Swift - Fatal编程技术网

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) })
    }
}