【问题标题】:Invalid Redeclaration of function in SwiftSwift中函数的无效重新声明
【发布时间】:2014-11-14 05:50:32
【问题描述】:

我正在尝试编写一些辅助函数,但遇到一些类似方法的“无效重新声明”错误。如果有人能解释为什么这些方法会发生冲突,我将非常感激。

func CGRectModify(rect: CGRect, x: CGFloat) -> CGRect {
    return CGRectMake(x, rect.origin.y, rect.size.width, rect.size.height)
}

func CGRectModify(rect: CGRect, y: CGFloat) -> CGRect {
    return CGRectMake(rect.origin.x, y, rect.size.width, rect.size.height)
}

func CGRectModify(rect: CGRect, width: CGFloat) -> CGRect {
    return CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height)
}

func CGRectModify(rect: CGRect, height: CGFloat) -> CGRect {
    return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
}

我认为由于第二个参数具有不同的外部名称,因此该方法将被理解为具有不同的签名。似乎情况并非如此。

我一直在使用 Apple 的文档作为参考,但在 Local and External Parameter Names for Methods 部分我找不到我的答案。非常感谢任何输入。

【问题讨论】:

    标签: function swift compiler-errors


    【解决方案1】:

    函数的“自动外部参数名称”规则与方法不同。

    Swift 根据可调用对象的类型应用不同的规则。

    1. 函数/闭包document

      不执行“自动外部参数名称”。

      func f(x:Int, y:Int) { /* ... */ }
      let c =  { (x:Int, y:Int) -> Void in /* ... */ }
      
      f(1, 2)
      c(1, 2)
      
    2. 初始化器document

      “自动外部参数名称”是每个参数的默认值。

      class Foo {
          init(x:Int, y:Int) { /* ... */ }
      }
      
      let foo = Foo(x: 1, y: 2)
      
    3. 方法document

      “自动外部参数名称”除了用于第一个参数。

      extension Foo {
          func bar(x:Int, y:Int) { /* ... */ }
      }
      
      foo.bar(1, y:2)
      
    4. 下标 → 文档丢失?

      不执行“自动外部参数名称”。

      extension Foo {
          subscript(x:Int, y:Int) -> Void {
              get { /* ... */ }
          }
      }
      
      foo[1, 2]
      

    还有一个特殊的规则...

    • 默认值

      func fz(x:Int, y:Int, z:Int = 1) { /* ... */ }
      
      fz(1, 1, z: 1)
      

    当然,您可以使用以下方法覆盖这些默认行为:

    • _ name:Type:禁用“自动外部参数名称”
    • #name:Type:强制“自动外部参数名称”
    • externalName internalName:Type: 显式外部名称

    【讨论】:

      【解决方案2】:

      这实际上看起来像是文档中的一个错误。在我最初链接的部分中,Local and External Parameter Names for Methods 写了以下说明。

      此默认行为有效地将该方法视为您在 numberOfTimes 参数之前写了一个井号 (#):

      func incrementBy(amount: Int, #numberOfTimes: Int) { 
            count += amount * numberOfTimes
      }
      

      事实并非如此。当我在第二个参数中添加井号 (#) 时,不会发生编译器错误。

      func CGRectModify(rect: CGRect, #height: CGFloat) -> CGRect {
          return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 2013-05-02
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      相关资源
      最近更新 更多