我正在尝试使用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方法调用之前,否则它尝试匹配第一个函数
我对类型缺少什么?
答案 0 :(得分:1)
您的方法equalToArray<T, S>
不知道T
是一个集合,因此上述通用hasCount(...)
方法的结果将无法分配给您的方法v
(因为这些结果会将Matcher<T>
个实例限制为T
:s Collection
:s)。即,v
对于非约束Matcher<T>
属于T
类型,这意味着,在编译器的眼中,例如对T.IndexDistance
:T
的{{1}}没有v
。
如果您向方法的Collection
添加T
类型约束,则hasCount(...)
结果到v
的分配应该编译:
func equalToArray<T: Collection, S>(_ vector: Array<S>) -> Matcher<T> {
let v: Matcher<T> = Hamcrest.hasCount(16)
return v
}
在一个完美的世界中,编译器可以给我们一个更有说服力的错误信息,比如
错误:(16,31)'
hasCount
'生成'Matcher<T>
',其中'T: Collection
', 不是预期的上下文结果类型“Matcher<T>
”
现在,我不知道你打算在这里测试什么,但正如@Hamish指出的那样,你可能真的想要返回Matcher<[S]>
并放弃T
占位符。例如。使用提供的count
参数的vector
属性作为hasCount(...)
的参数?
func equalToArray<S>(_ vector: Array<S>) -> Matcher<[S]> {
return hasCount(vector.count)
}
我自己没有使用过Hamcrest,我可能会弄错,但是基于对SwiftHamcrest文档的快速浏览,我相信如上所定义的equalToArray(_:)
将构造一个“向量相等”的匹配器(函数的wrt语义) name)仅基于两个向量的计数,在这种情况下,以下断言将成功
let arr1 = ["foo", "bar"]
let arr2 = ["bar", "baz"]
assertThat(arr1, equalToArray(arr2)) // success! ...
但这只是一个署名,因为您没有向我们展示您打算应用equalToArray(_:)
方法/匹配器的上下文;也许你只是向我们展示了一个最小的例子,而你自定义匹配器的实际主体更忠实于方法的名称。