2017-04-17 40 views
0

我想使用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方法调用之前,否则它试图匹配到第一个函数

我缺少什么类型?

+1

看起来你想返回一个'Matcher <[S]>'而不是'Matcher '(然后删除通用占位符'T')。虽然我不确定'vector'参数的用途。 – Hamish

+0

@Hamish - 这是一个减少案例,我想要其他匹配器 - 所以是在这个例子中不需要参数更全面的例子是func equalToArray (_ vector:Array ) - > Matcher { \t设v:匹配器 = Hamcrest.hasCount(vector.count) \t回报v } – Mark

回答

1

你的方法equalToArray<T, S>不知道T是一个集合,所以从上面的通用hasCount(...)方法的结果不会分配给v在你的方法(因为这些结果返回Matcher<T>情况下限制为T:■是Collection: S)。即,对于非约束的T,即vMatcher<T>的类型,这意味着在编译器的眼中,存在例如没有T.IndexDistancevT: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(_:)方法/匹配器;也许你只是向我们展示一个最简单的例子,而你自定义的匹配器的实体更接近方法的名称。

+0

是的,我知道这是不是向量的一个很好的比较 - 我刚刚晋级的例子下降到一个错误,希望理解这将帮助我休息 - 但它不:( – Mark

+0

一般来说,我试图传递一个数组到一个函数采取T ... - 不幸的是不可能https://bugs.swift.org/browse/SR -128所以你的答案的第一部分解决了我的问题,但是一般公关oblem是不可修复的 - 我需要重写外部库以获取阵列:( – Mark

+0

@Mark啊是的,这是一个已知的限制,但对于许多用例,您可以通过提供一个超载来处理'[T]'参数而不是'T ...'(这将是你有实现逻辑的重载),并让'T ...'方法简单地调用后者的重载。请记住,可变参数只是它所提供函数体中的一个数组。见例如[这个要点](https://gist.github.com/dfrib/5dcb0764f849e6d454cd57ff05109582)为例。可能这样的解决方法可能对您的情况有用。 – dfri