【问题标题】:In Swift, a generic function that returns a function of the same type gives me "Cannot explicitly specialize a generic function"在 Swift 中,返回相同类型函数的泛型函数给了我“无法显式特化泛型函数”
【发布时间】:2016-03-09 18:06:03
【问题描述】:

此函数接受Void -> T 函数并返回Void -> T 函数。

func future<T>(f: Void -> T) -> Void -> T {
    let queue = dispatch_queue_create("com.test.lockQueue", nil)
    var results: T?

    dispatch_async(queue) {
        results = f()
    }

    return {
        dispatch_sync(queue) {}
        return results!
    }
}

如果我这样使用它:

let f = future<Int> {
    NSThread.sleepForTimeInterval(2)
    return 10
}

我收到错误“无法明确专门化泛型函数”。

如果我像这样将显式类型设置为Void -&gt; Int

let f: Void -> Int = future {
    NSThread.sleepForTimeInterval(2)
    return 10
}

它可以工作,但看起来不太好。 我可以更改函数以便在第一个示例中使用它吗?

【问题讨论】:

    标签: swift generics


    【解决方案1】:

    您可以将函数定义为本地函数并传递它。

    func sleepAndReturn() -> Int { 
        NSThread.sleepForTimeInterval(2)
        return 10
    }
    
    let f = future(sleepAndReturn)
    

    您也可以使用in 语法来指定类型。

    let f = future({ () -> Int in  
        NSThread.sleepForTimeInterval(2)
        return 10
    })
    

    或更短:

    let f = future({ _ -> Int in  
        NSThread.sleepForTimeInterval(2)
        return 10
    })
    

    【讨论】:

      【解决方案2】:

      我认为它应该像这样工作:

      let f = future {
          NSThread.sleepForTimeInterval(2)
          return 10
      }
      

      ...或者如果这对 Swift 来说太难了,那么你可以像这样指定闭包参数:

      let f = future { Void -> Int in
          NSThread.sleepForTimeInterval(2)
          return 10
      }
      

      【讨论】:

      • 类似的代码确实在我的 x86_64-unknown-linux-gnu 目标上运行。稍后将检查 XCode。无论如何,问题在于没有明确专门化泛型。 Swift 应该能够从上下文中推断出 gereric 参数的特定类型。
      • 阅读它,我现在明白了编译器无法专门化泛型函数意味着什么。第二个例子@AntonBronnikov 是我想我会选择的例子。
      【解决方案3】:

      您可以将函数包装在结构中并像这样使用它:

      struct Future<T> {
          static func create(f: Void -> T) -> Void -> T {
              let queue = dispatch_queue_create("com.test.lockQueue", nil)
              var results: T?
      
              dispatch_async(queue) {
                  results = f()
              }
      
              return {
                  dispatch_sync(queue) {}
                  return results!
              }
          }
      }
      
      let f = Future<Int>.create {
          NSThread.sleepForTimeInterval(2)
          return 20
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-16
        • 2018-12-24
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 2020-10-26
        • 1970-01-01
        相关资源
        最近更新 更多