2015-11-07 115 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; 
    } 
}