【问题标题】:Generic parameter 'T' could not be inferred / Cannot explicitly specialize a generic function无法推断通用参数“T”/无法明确专门化通用函数
【发布时间】:2017-04-24 18:29:19
【问题描述】:

我在 Xcode 7.3.1 的 Swift 项目中编写了一个带有此签名的函数:

func DLog<T>(@autoclosure object: () -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
}

编译器为此调用抱怨Generic parameter 'T' could not be inferred

DLog({ var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; })

当我尝试提供它抱怨Cannot explicitly specialize a generic function的类型时:

DLog<String>({ var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; })

我尝试了其他几种方法,但编译器都没有满意。我也没有找到如何解决这个案例的提示。

如何在() =&gt; T 参数中构建文本并将其正确传递给函数?

【问题讨论】:

    标签: swift xcode generics swift2


    【解决方案1】:

    由于@autoclosure 属性,编译失败。当您将某个表达式传递给采用@autoclosure 的函数时,编译器会创建一个不带参数的闭包,该闭包会返回该表达式的结果。因此,当您传递 { var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; } 时,编译器会创建一个闭包,返回一个闭包返回字符串。

    要解决此问题,您可以将() 添加到表达式的末尾:

    DLog({ () -> String in var text = "Returning output list\n"; for outline in outlines { text = text + outline.debugDescription + "\n"; }; return text; }())
    

    或将表达式简化为简单的方法调用,例如

    DLog(outlines.reduce("Returning output list\n") { $0 + $1.debugDescription + "\n"; })
    

    【讨论】:

      【解决方案2】:

      我不知道为什么会导致它,但是在 swift 3 中编译它会出现此错误消息:

      无法推断复杂的闭包返回类型;添加显式类型以消除歧义

      所以我尝试显式添加闭包的返回类型:

      DLog(
          { () -> String in 
              var text = "Returning output list\n" 
              for outline in outlines { 
                  text = text + outline.debugDescription + "\n"; 
              } 
              return text 
          }
      )
      

      它成功了。

      【讨论】:

      • 我在 Xcode 7.3.1 中收到 Cannot invoke 'DLog' with an argument list of type '(() -&gt; String)'
      • 这可能是因为您在参数类型为@autoclosure 时指定了一个闭包?你不能@autoclosure 闭包。
      • @alik 尝试移除自动关闭属性
      • 我有Closure parameter prior to parameters with default arguments will not be treated as a trailing closure 所以我把闭包放在参数列表的末尾。但是,调用var value = object(); print("\(fileURL) \(function)[\(line)]: " + String(reflecting: value)); 会导致打印(Function) 而不是text 的内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2021-11-13
      相关资源
      最近更新 更多