斯威夫特没有找到正确的类型
我想使用SwiftHamcrest斯威夫特没有找到正确的类型
我有一个函数
func equalToArray<T, S>(_ vector:Array<S>) -> Matcher<T> {
let v: Matcher<T> = Hamcrest.hasCount(16)
return v
}
这给出了一个错误
Error:(16, 31) 'hasCount' produces 'Matcher<T>', not the expected contextual result type 'Matcher<T>'
SwiftHamcrest有两个hasCount功能
public func hasCount<T: Collection>(_ matcher: Matcher<T.IndexDistance>) -> Matcher<T>
public func hasCount<T: Collection>(_ expectedCount: T.IndexDistance) -> Matcher<T>
为什么我的代码抱怨不是它返回所需的相同类型。
作为一个说明,可能是一个不同的问题,我不得不添加Hamcrest。在hasCount方法调用之前,否则它试图匹配到第一个函数
我缺少什么类型?
你的方法equalToArray<T, S>
不知道T
是一个集合,所以从上面的通用hasCount(...)
方法的结果不会分配给v
在你的方法(因为这些结果返回Matcher<T>
情况下限制为T
:■是Collection
: S)。即,对于非约束的T
,即v
是Matcher<T>
的类型,这意味着在编译器的眼中,存在例如没有T.IndexDistance
为v
的T
:s型。
如果添加Collection
类型约束你的方法的T
,从hasCount(...)
结果v
分配应编译:
func equalToArray<T: Collection, S>(_ vector: Array<S>) -> Matcher<T> {
let v: Matcher<T> = Hamcrest.hasCount(16)
return v
}
在一个完美的世界中,编译器可能已经给了我们一个更有力错误消息,沿着
Error:(16, 31) '
hasCount
' produces 'Matcher<T>
' where 'T: Collection
', not the expected contextual result type 'Matcher<T>
'
现在行说,我不知道你打算给TE什么在这里,但正如@Hamish指出的那样,您可能实际上想要返回Matcher<[S]>
并删除T
占位符。例如。使用提供的vector
参数的count
属性作为hasCount(...)
的参数?
func equalToArray<S>(_ vector: Array<S>) -> Matcher<[S]> {
return hasCount(vector.count)
}
由于没有使用Hamcrest自己,我可能是错的,但基于快速掠过SwiftHamcrest文档,我相信equalToArray(_:)
如上定义将构建一个匹配的“向量平等”(函数的WRT语义名)仅基于两个向量的数量,在这种情况下,下面的断言将是一个成功
let arr1 = ["foo", "bar"]
let arr2 = ["bar", "baz"]
assertThat(arr1, equalToArray(arr2)) // success! ...
但是,这仅仅是一个署名,因为你已经不是我们这里出你打算申请的上下文equalToArray(_:)
方法/匹配器;也许你只是向我们展示一个最简单的例子,而你自定义的匹配器的实体更接近方法的名称。
是的,我知道这是不是向量的一个很好的比较 - 我刚刚晋级的例子下降到一个错误,希望理解这将帮助我休息 - 但它不:( – Mark
一般来说,我试图传递一个数组到一个函数采取T ... - 不幸的是不可能https://bugs.swift.org/browse/SR -128所以你的答案的第一部分解决了我的问题,但是一般公关oblem是不可修复的 - 我需要重写外部库以获取阵列:( – Mark
@Mark啊是的,这是一个已知的限制,但对于许多用例,您可以通过提供一个超载来处理'[T]'参数而不是'T ...'(这将是你有实现逻辑的重载),并让'T ...'方法简单地调用后者的重载。请记住,可变参数只是它所提供函数体中的一个数组。见例如[这个要点](https://gist.github.com/dfrib/5dcb0764f849e6d454cd57ff05109582)为例。可能这样的解决方法可能对您的情况有用。 – dfri
看起来你想返回一个'Matcher '而不是'Matcher'(然后删除通用占位符'T')。虽然我不确定'vector'参数的用途。 –
Hamish
@Hamish - 这是一个减少案例,我想要其他匹配器 - 所以是在这个例子中不需要参数更全面的例子是func equalToArray(_ vector:Array
) - > Matcher { \t设v:匹配器 = Hamcrest.hasCount(vector.count) \t回报v } –
Mark