Swift 找不到正确的类型
Swift not finding the correct type
我正在尝试使用 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
方法(因为这些结果 returns Matcher<T>
个实例被限制为 T
:s 即 Collection
:s)。即,v
是非约束 T
类型的 Matcher<T>
,这意味着,在编译器看来,例如v
:s 类型的 T
没有 T.IndexDistance
。
如果您向方法的 T
添加 Collection
类型约束,则从 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>
'
现在,我不知道你打算在这里测试什么,但正如@Hamish 指出的那样,你可能实际上想要 return a Matcher<[S]>
并删除 T
占位符。例如。使用提供的 vector
参数的 count
属性 作为 hasCount(...)
?
的参数
func equalToArray<S>(_ vector: Array<S>) -> Matcher<[S]> {
return hasCount(vector.count)
}
我自己没有使用过 Hamcrest,我可能会弄错,但基于对 SwiftHamcrest 文档的快速浏览,我相信如上定义的 equalToArray(_:)
会为 "vector equality" 构造一个匹配器(w.r.t. 函数名称的语义)仅基于两个向量的计数,在这种情况下,以下断言将是成功的
let arr1 = ["foo", "bar"]
let arr2 = ["bar", "baz"]
assertThat(arr1, equalToArray(arr2)) // success! ...
但这只是署名,因为您还没有向我们展示您打算应用 equalToArray(_:)
method/matcher 的上下文;也许您只是向我们展示了一个最小的示例,而您的自定义匹配器的实际主体更符合方法的名称。
我正在尝试使用 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
方法(因为这些结果 returns Matcher<T>
个实例被限制为 T
:s 即 Collection
:s)。即,v
是非约束 T
类型的 Matcher<T>
,这意味着,在编译器看来,例如v
:s 类型的 T
没有 T.IndexDistance
。
如果您向方法的 T
添加 Collection
类型约束,则从 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>
'
现在,我不知道你打算在这里测试什么,但正如@Hamish 指出的那样,你可能实际上想要 return a Matcher<[S]>
并删除 T
占位符。例如。使用提供的 vector
参数的 count
属性 作为 hasCount(...)
?
func equalToArray<S>(_ vector: Array<S>) -> Matcher<[S]> {
return hasCount(vector.count)
}
我自己没有使用过 Hamcrest,我可能会弄错,但基于对 SwiftHamcrest 文档的快速浏览,我相信如上定义的 equalToArray(_:)
会为 "vector equality" 构造一个匹配器(w.r.t. 函数名称的语义)仅基于两个向量的计数,在这种情况下,以下断言将是成功的
let arr1 = ["foo", "bar"]
let arr2 = ["bar", "baz"]
assertThat(arr1, equalToArray(arr2)) // success! ...
但这只是署名,因为您还没有向我们展示您打算应用 equalToArray(_:)
method/matcher 的上下文;也许您只是向我们展示了一个最小的示例,而您的自定义匹配器的实际主体更符合方法的名称。