2015-11-07 72 views
1

我想使用泛型執行快速執行請求函數。我想打電話,並根據我返回的結果切換枚舉結果。然而,我不明白:'不能用類型參數列表(NSURLRequest,(Result < __>) - >())'調用performRequest爲什麼我不能在這裏有一個未命名的參數?我也嘗試了類似以下內容:r < MyStruct> ---但我然後得到預期的表達式錯誤。任何幫助解釋上述結果< _>錯誤將不勝感激。謝謝。泛型執行請求,使用泛型

enum Result<A> { 
    case Value 
    case Error 
} 

func performRequest<A>(request:NSURLRequest, callback:(Result<A>) ->()) { 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in 
    callback(parseResponse(data, response: response, error: error)) 
    } 
    task.resume() 
} 

class SampleClass { 

let request = NSURLRequest(URL: NSURL(string: "www.google.com")!) 

init() { 
    performRequest(request) { r in -------- errors out 
     switch r { 
      case .Value: 

      case .Error: 
    } 
} 

}

+0

'parseResponse'的簽名是什麼? –

回答

1

的問題是,當你使用performRequest,你有沒有給你打算使用泛型參數編譯器足夠的信息。缺少的關鍵部分是parseResponse需要返回Result,該參數與回調相同。但是,在您提供的片段中,parseResponse不是通用的。

我相信這會做你想要的。在這種情況下,我使用StringResult進行了參數化設置,但您可以替換任何其他類型。

// multi-purpose (generic) Result type 
enum Result<A> 
{ 
    case Value(A) // because you parameterised the enum, you might as well take advantage of the type 
    case Error 
} 

// this is a custom parser, you may substitute your own that returns a different type 
func parseString(data:NSData?, response:NSURLResponse?, error:NSError?) -> Result<String> { 
    if let _ = error { 
     return Result.Error 
    } 
    return Result.Value("Success") 
} 

// this function is completely generic, but the parser and callback need to be compatible 
func performRequest<A>(request:NSURLRequest, 
         parser:(NSData?, NSURLResponse?, NSError?) -> Result<A>, 
         callback:(Result<A>) -> Void) { 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
     (data, response, error) -> Void in 
     callback(parser(data, response, error)) 
    } 
    task.resume() 
} 

let request = NSURLRequest(URL: NSURL(string: "www.google.com")!) 

// actual invocation, now I need to pass in a concrete parser and callback with a specific type 
performRequest(request, parser: parseString) { // parseString returns a Result<String> 
    r in 
    switch r { 
    case .Value(let value): 
     // because I passed in a parser that returns a Result<String>, I know that "value" is a String here 
     print("Succeeded with value: \(value)") 
     break; 
    case .Error: 
     print("an error occurred") 
     break; 
    } 
}