使用 `self` 作为默认参数

Use `self` as a default parameter

我可以使用 self 作为 Swift 中的默认参数吗?这段代码感觉很直接,但我不明白编译器回击的消息:

func printTree(node: TreeNode = self, tabs: String = "") {
  println(tabs + node.name!)
  node.children.forEach { printTree(node: [=10=], tabs: tabs+"\t") }
}

错误:

'TreeNode -> () -> TreeNode' is not convertible to 'TreeNode'

嗯?

可能还有其他方法可以解决树遍历问题,但实际上我只是对默认参数限制感到好奇。这是真的吗?文档中是否提到了这一点?我找不到一个。

更新:

我是从头开始做的,没有任何依赖(我之前有一个 class 层次结构和一个自定义的 forEach 猴子补丁)。它仍然错误:

class PeanutButterJelly {
  var children: [PeanutButterJelly]?
  func doDance(){ println("dancing") }
  func everybodyDanceNow(pbj: PeanutButterJelly = self) {
    pbj.doDance()
    if let children = pbj.children {
      for child in children { child.doDance() }
    }
  }
}

错误:

Swift compilation error: unresolved identifier 'self'

Xcode6.3.2

之所以unresolved identifier 'self'是一个实例的隐含范围属性 self'是在每个实例方法中。如果您在示例中将默认值从 self 更改为 children,您将看到错误

'PeanutButterJelly.Type' does not have a member named 'children'

不像 objc 中有另一个版本的 self 引用 class 的类型没有这样的东西是 swift

Can I use self as a default parameter in Swift

没有。这与初始化实例方法时不能说 self 的原因基本相同:

class TreeNode {
    var otherNode : TreeNode = self // Use of unresolved identifier `self`
    func printTree(tree:TreeNode = self) { } // Use of unresolved identifier `self`
}

在您定义这个实体(属性或方法)时,没有self这样的东西。后面会有一个self,当这个方法被调用时,在函数的body里面——因为函数会被调用在某些情况下,即 self.

做您想做的事情的一种简单方法是使此参数成为具有 nil 默认值的可选参数。然后,在函数体中,检查 nil 并使用 self:

class TreeNode {
    func printTree(tree:TreeNode? = nil) {
        let treeToPrint = tree ?? self
        // do stuff
    }
}

现在不带参数调用 printTree 是合法的,它会做你想做的事:

TreeNode().printTree()