Xcode 8:函数类型不能让参数标签破坏我的构建

时间:2016-09-21 09:56:25

标签: ios swift xcode8 completionhandler

似乎由于某种原因,Swift选择通过强制用户删除完成处理程序参数标签来降低编码。我已经阅读过Swift的讨论,仍然认为这是一个错误。至少他们可以让它成为可选的。

使用Xcode 8构建时 - 是否有办法强制编译器使用Swift 2.3,所以我不再会遇到这些错误? 我已经更新了使用旧版Swift的选项(在构建设置下) legacy support in xcode 但我似乎仍然得到这个错误:

  

函数类型不能有参数标签'isloggedIn';使用 '_'   代替

error Xcode 8

如何在完成处理程序中保留标签?

5 个答案:

答案 0 :(得分:92)

Swift设计者决定禁止函数类型的参数标签。

这里解释了推理:https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md

这是一个令人沮丧和可疑的选择,因为禁止参数标签使得更容易错误地调用闭包,这似乎比简化语言的类型系统更重要。

可用性>思想。

答案 1 :(得分:21)

需要考虑的解决方法。你不能这样做:

func doStuff(completion: (foo: Int, bar: String) -> Void) {
    ...
    completion(foo: 0, bar: "")
}

...但你可以这样做:

func doStuff(completion: ((foo: Int, bar: String)) -> Void) {
    ...
    completion((foo: 0, bar: ""))
}

即。你的闭包有一个未命名的参数,它是一个元组,在本例中为(foo: Int, bar: String)

它以自己的方式丑陋,但至少你保留了参数标签。

免责声明:我没有考虑过这种方法的捕获或性能影响。

答案 2 :(得分:10)

基于上述信息 - 似乎是真正解决这个问题的唯一方法,并确保其效果是将提案提交到 使参数标签可选,其视图为:

  1. 提高开发速度(没有参数标签,每次我们放入完成处理程序时,它都要求我们向上滚动到方法的顶部。
  2. 减少错误:(由于错误的完成处理程序条目,特别是那些期望布尔值的条目,我已经遇到了几个错误)
  3. 让代码在团队成员中更具可读性。不是每个人都只有一个团队成员,因此能够轻松拿起其他人的代码是必须的。
  4. 最后,良好的编程习惯意味着解决方案看起来应该与正在开发的实际项目一样。 completionhandler: (newvalues, nil)看起来不像被管理的项目而是completionhandler(results: newValue, error:nil)
  5.   

    我很乐意为阅读此内容的人分享他们的反馈/意见   在我提交它之前,我可以证明还有其他人   支持这个。

    编辑: 我在这里提交了这个节目:  https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161010/028083.html 似乎已达成一致意见。看起来它会发生,但讨论的是这是否作为Swift 4改进提交(极有可能)

答案 3 :(得分:9)

你必须使用_来使你的参数未命名,这是不幸的。而不是将_添加到每个参数然后盲目地调用你的函数我建议制作一个包装器对象。

由于丢失函数类型的命名参数会增加您使用错误值调用函数的风险,我建议将参数包装在结构中并将其作为函数的唯一参数。

这样,您的struct字段就会被命名,并且只有一种类型的值可以传递到您的函数中。它比我们能够命名函数的参数更麻烦,但我们不能。至少这样你会更安全,而且你会感觉不那么脏。

struct LineNoteCellState {

    var lineNoteText: String?
    var printOnInvoice = false
    var printOnLabel = false
}

这是一个使用它的例子:

cell.configure(editCallback: { (_ state: LineNoteCellState) in

    self.lineNoteText = state.lineNoteText
    self.printOnInvoice = state.printOnInvoice
    self.printOnLabel = state.printOnLabel
})

答案 4 :(得分:4)

半解决方法,请注意 _

completion: (_ success: Bool) -> Void