[英]Swift 4 generic array as parameter in generic class
我有一个用于测试的匹配器
class GWMatcher<ResultType> {
let result: ResultType
let message: String
init(result: ResultType, message: String) {
self.result = result
self.message = message
}
}
我想添加扩展以将其与数组一起使用。 我希望它像这样:
extension GWMatcher where ResultType == [Equatable] {
func checkEqual(_ expression: ResultType) {
XCTAssertEqual(self.result, expression, self.message)
}
}
但是编译器说:
无法使用类型为
([Equatable], Array<Equatable>, String)
的参数列表调用XCTAssertEqual
。
有没有人有想法,是否有可能做这样的事情?
我相信您遇到了 Swift 类型系统的边缘情况。 特别是,通用约束:
extension GWMatcher where ResultType == [Equatable]
应该真正指定为:
extension GWMatcher where ResultType == [T] where T: Equatable
但目前不支持最后一种形式(对于扩展)。 这一点很重要,因为斯威夫特协议不符合本身,这将需要忠于[Equatable]
如预期的工作(这就是为什么一个具体类型T
是必需的)。 我知道,非常棘手......;)
此外,标准Equatable
协议只能用作通用约束,因为它具有Self
要求(使用关联类型的协议也有类似的行为)。 这种 Swift 限制也可能是罪魁祸首。
解决方法。 无论如何,作为一种不太安全的解决方法,请尝试以下操作:
extension GWMatcher {
func checkEqual<T: Equatable>(_ expression: [T]) {
guard let result = self.result as? [T] else {
XCTFail("Expected type \([T].self)")
return
}
XCTAssertEqual(result, expression)
}
}
这不像您的原始设计那样类型安全,因为它将可用于所有GWMatcher
类型,包括那些ResultType
未键入为[Equatable]
类型。 尽管如此,它应该按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.