2017-04-17 77 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