【问题标题】:Syntax of Block in SwiftSwift 中块的语法
【发布时间】:2014-07-25 04:17:24
【问题描述】:

我正在尝试从 Objective-C 重写为 Swift,但我无法确定语法或理解文档

这是我在 Objective-C 中编写的一个简化示例:

[UIView animateWithDuration:10.0 animations:^{self.navigationController.toolbar.frame = CGRectMake(0,10,0,10);}];

如何在 Swift 中编写这个?

这是自动完成提供的模板:

UIView.animateWithDuration(duration: NSTimeInterval, animations: (() -> Void))

【问题讨论】:

    标签: ios swift swift3


    【解决方案1】:

    这是快速关闭格式:

    {(parameter:type, parameter: type, ...) -> returntype in
        //do stuff  
    }
    

    这是你应该做的:

    //The animation closure will take no parameters and return void (nothing).
    UIView.animateWithDuration(duration: NSTimeInterval, animations: {() -> Void in
        //Animate anything.
    })
    

    这里是 documentation 用于闭包。

    【讨论】:

      【解决方案2】:

      由于动画参数的预期参数类型和返回类型是已知的,编译器可以毫无问题地推断出它们。这应该可行(尽管我目前没有可用的游乐场:

      UIView.animateWithDuration(10.0, animations: {
        self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
      })
      

      有关闭包的更多信息,请参阅chapter in the swift docs

      注意 CGRect() - developer docs 显示 CGRect() 在 swift 代码中使用。也许它需要导入?

      cmets 更新:您也可以像这样使用尾随闭包:

      UIView.animateWithDuration(10.0) {
        self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
      }
      

      【讨论】:

      • 也许尾随闭包会更简单? :)
      • @Jiaaro 命名参数不是问题。它必须是最后一个参数,仅此而已。
      • 只是我还是尾随闭包更令人困惑?有谁知道这受什么语言影响或为什么有意义?
      • @tony Groovy 具有尾随闭包语法。有more similarities
      【解决方案3】:

      以下代码可以指导您编写自己的块。

      class func testFunc(completion: ((list : NSArray!) -> Void)?) {
          //---  block code.
          if completion! != nil {
              completion! (list: NSArray())
          }
      }
      

      你可以这样称呼它——

      className.testFunc {
      (list: NSArray!) -> Void in
      }
      

      【讨论】:

        【解决方案4】:

        你基本上可以用 3 种相同的方式来编写它:

        在闭包/代码块中写下正确的操作:

        UIView.animateWithDuration(10.0) {
          self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
        }
        

        这也称为尾随闭包(只有在闭包参数是last参数的情况下才能做尾随闭包)

        这并不意味着不再写入参数“动画”。它是写的,但就像上面的格式一样。


        准确地写在行内,大多数开发人员避免这样,因为用所有的括号和大括号来写有点麻烦。

        UIView.animateWithDuration(10.0, animations: {
          self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
        })
        

        (与尾随闭包相反,您写了名称,即“动画”) 这称为内联闭包


        以更模块化的方式编写

        UIView.animateWithDuration(duration: NSTimeInterval, animations: animatingFunc)
        
        func animatingFunc() {
          self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
        }
        

        记住参数“动画”的类型是() -> Void

        正如我们所做的那样,animatingFunc 不接受任何参数,即 '()' 并且不返回任何参数,即 'void'

        (在 Swift 中,函数是类型,可以作为参数传入) 有些人可能会说这更具可读性,有些人可能会说尾随闭包是......


        旁注1 你也可以什么都不做(这真的没有意义,但在许多其他处理程序/动画/完成处理程序中你可能不想做任何事情)

        UIView.animateWithDuration(duration: NSTimeInterval, animations: nil)
        

        旁注2

        当您必须捕获一个值时,闭包会变得更有趣。见this简单演示。 有关 Swift 闭包的更多信息,请参阅Apple's Documentation

        【讨论】:

          【解决方案5】:

          如何在 Swift 中声明闭包?

          1. 作为变量:

            var closureName: (ParameterTypes) -> ReturnType

          2. 作为可选变量:

            var closureName: ((ParameterTypes) -> ReturnType)?

          3. 作为类型别名:

            typealias ClosureType = (ParameterTypes) -> ReturnType

          4. 作为常数:

            let closureName: ClosureType = { ... }

          5. 作为另一个函数的参数:

            funcName(parameter: (ParameterTypes) -> ReturnType)

          注意:如果传入的闭包将超出方法的范围,例如如果要将其保存到属性中,则需要使用 @escaping 进行注释。

          1. 作为函数调用的参数:

            funcName({ (ParameterTypes) -> ReturnType in statements })

          2. 作为函数参数:

            array.sorted(by: { (item1: Int, item2: Int) -> Bool in return item1 < item2 })

          3. 作为隐含类型的函数参数:

            array.sorted(by: { (item1, item2) -> Bool in return item1 < item2 })

          4. 作为隐含返回类型的函数参数:

            array.sorted(by: { (item1, item2) in return item1 < item2 })

          5. 作为最后一个函数参数:

            array.sorted { (item1, item2) in return item1 < item2 }

          6. 作为最后一个参数,使用简写的参数名称:

            array.sorted { return $0 < $1 }

          7. 作为最后一个参数,带有一个隐含的返回值:

            array.sorted { $0 < $1 }

          8. 作为最后一个参数,作为对现有函数的引用:

            array.sorted(by: <)

          9. 作为具有显式捕获语义的函数参数:

            array.sorted(by: { [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })

          10. 作为具有显式捕获语义和推断参数/返回类型的函数参数:

            array.sorted(by: { [unowned self] in return $0 < $1 })

          本网站并非旨在详尽列出所有可能的闭包用途。
          ref:http://goshdarnclosuresyntax.com/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-13
            • 1970-01-01
            • 2014-07-29
            • 1970-01-01
            相关资源
            最近更新 更多