Swift 4 泛型数组作为泛型中的参数class
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)
}
}
但是编译器说:
Cannot invoke XCTAssertEqual
with an argument list of type ([Equatable], Array<Equatable>, String)
.
有没有人有想法,是否可以做这样的事情?
我相信您遇到了 Swift 类型系统的边缘情况。特别是,通用约束:
extension GWMatcher where ResultType == [Equatable]
确实应该指定为:
extension GWMatcher where ResultType == [T] where T: Equatable
但目前不支持最后一种形式(对于 extensions)。这很重要,因为 Swift 协议确实 不 符合自身,这需要符合 [Equatable]
按预期工作(这就是为什么具体类型 T
是必需的)。我知道,非常棘手... ;)
此外,标准 Equatable
protocol can only be used as a generic constraint because it has Self
要求(使用 关联类型 的协议也有类似的行为)。这个 Swift 限制也可能是这里的罪魁祸首。
解决方法。无论如何,作为 less 类型安全的解决方法,试试这个:
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]
。尽管如此,它应该会按预期工作。
我有一个用于测试的匹配器
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)
}
}
但是编译器说:
Cannot invoke
XCTAssertEqual
with an argument list of type([Equatable], Array<Equatable>, String)
.
有没有人有想法,是否可以做这样的事情?
我相信您遇到了 Swift 类型系统的边缘情况。特别是,通用约束:
extension GWMatcher where ResultType == [Equatable]
确实应该指定为:
extension GWMatcher where ResultType == [T] where T: Equatable
但目前不支持最后一种形式(对于 extensions)。这很重要,因为 Swift 协议确实 不 符合自身,这需要符合 [Equatable]
按预期工作(这就是为什么具体类型 T
是必需的)。我知道,非常棘手... ;)
此外,标准 Equatable
protocol can only be used as a generic constraint because it has Self
要求(使用 关联类型 的协议也有类似的行为)。这个 Swift 限制也可能是这里的罪魁祸首。
解决方法。无论如何,作为 less 类型安全的解决方法,试试这个:
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]
。尽管如此,它应该会按预期工作。