我使用ReactiveSwift
。有两种协议:CommonProtocol
和SpecificProtocol
。当我在map
函数中使用SpecificProtocol
时,出现错误Type 'any SpecificProtocol' cannot conform to 'Equatable'。但是,使用ConreateItem
完全没有问题
protocol CommonProtocol {}
protocol SpecificProtocol: CommonProtocol, Equatable
extension SpecificProtocol where Self: Equatable {
static func == (lhs: Self, rhs: Self) -> Bool { return true }
}
class ConreateItem: SpecificProtocol{}
var messages = MutableProperty<[CommonProtocol]?>(nil)
messages.producer
// .map({ $0 as? [ConreateItem] }) //that is ok
.map({ $0 as? [any SpecificProtocol] })//Type 'any SpecificProtocol' cannot conform to'Equatable'
.skipRepeats()
我不明白为什么/如何将SpecificProtocol
转换为any SpecificProtocol
。什么是正确的方式来实现协议上的Equatable
约束,以便我可以在map
函数中使用它(在我的情况下,高阶函数需要Equatable
)map
是ReactiveSwift
1条答案
按热度按时间bihw5rsg1#
Equatable
中的tl;dr==
要求两个参数具有相同的具体类型。如果编译器只知道两个示例中的每一个都是any Equatable
,则无法确定这一点。如果不仔细研究
skipNil()
,看起来它需要一个符合Equatable
的对象序列。SpecificProtocol
没有声明与Equatable
的一致性,它只是声明了一个函数==
(它有一个编译器错误,因为它没有返回Bool
),所以有一个类型错误。顺便说一下,注意protocols在Swift中不是类型,这就是为什么“any”在那里。它是“任何类型符合
SpecificProtocol
的东西”的缩写。在将来的某个时候,您将不得不在声明中显式地写入any
。例如[any SpecificProtocol]
要使SpecificProtocol示例符合
Equatable
,您需要您可以保留扩展来定义默认的
==
函数,也可以允许具体类型定义自己的函数实现。更新
即使
SpecificProtocol
符合Equatable
,您也会看到错误消息的原因是,不能比较都符合Equatable
的任意类型的示例是否相等。不允许"foo" == 3
,即使String
和Int
都是相等的。为了使从
map
返回的数组是Equatable,它必须能够将它的元素与另一个相同类型的数组的元素进行比较,如果你对这些元素一无所知,除了它们都符合SpecificProtocol
之外,你不能比较它们的相等性,因为Equatable
一致性要求==
的两个参数都是相同的 * 具体 *类型。另外,我认为map闭包不应该返回数组。我觉得应该是
.map({ $0 as? any SpecificProtocol })