Can I use self
as a default parameter in Swift? This code feels pretty straight forward but I don't understand the message the compiler is kicking back:
func printTree(node: TreeNode = self, tabs: String = "") { println(tabs + node.name!) node.children.forEach { printTree(node: $0, tabs: tabs+"\t") } }
Error:
'TreeNode -> () -> TreeNode' is not convertible to 'TreeNode'
Huh?
There are probably other ways I could solve the tree traversal but I'm actually just curious about the default parameter restriction. Is this a real thing? Is there a mention of this in the docs? I couldn't find one.
Update:
I did this from scratch with no dependencies (I had a class heirarchy and a custom forEach
monkey patch involved before). It still errors:
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() } } } }
Error:
Swift compilation error: unresolved identifier 'self'
Xcode 6.3.2
The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.
In JavaScript, function parameters default to undefined . However, it's often useful to set a different default value. This is where default parameters can help. In the past, the general strategy for setting defaults was to test parameter values in the function body and assign a value if they are undefined .
self is only a reference to the current instance within the method. You can't change your instance by setting self .
If you see the method definition "def area(self): ” , here "self" is used as a parameter in the method because whenever we call the method, the object (instance of class) is automatically passed as a first argument along with other arguments of the method.
Can I use self as a default parameter in Swift
No. This is basically for the same reason that you can't say self
when initializing an instance method:
class TreeNode { var otherNode : TreeNode = self // Use of unresolved identifier `self` func printTree(tree:TreeNode = self) { } // Use of unresolved identifier `self` }
At the time you're defining this entity (property or method), there is no such thing as self
. There will be a self
later, when this method is called, inside the body of the function - because the function will be called on some instance, namely self
.
One easy way to do what you want to do is to make this parameter an Optional with a nil
default value. Then, in the body of the function, check for nil
and use self
:
class TreeNode { func printTree(tree:TreeNode? = nil) { let treeToPrint = tree ?? self // do stuff } }
Now it's legal to call printTree
with no parameter, and it does what you want it to do:
TreeNode().printTree()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With