Home > OS >  Providing default instance arguments for (recursive) extension in Swift
Providing default instance arguments for (recursive) extension in Swift

Time:09-20

I was having fun while practicing a Kata.
I wanted to implement one of the functions in my solution as an extension of Int, because I liked the idea of having pretty syntax. The function, in itself, looks like this:

func decomposed(_ n: Int) -> [Int] {
    if n > 10 {
      return n.decomposed(n / 10)   [n % 10] 
    } else {
      return [n]
    }
  }

Now, I've tried to implement it as an extension. Due to the fact that I would like to use it like 420.decomposed(), I figured that I would need the instance as the default argument. I proceeded with:

extension Int {
  func decomposed(_ n: Int = self) -> [Int] {
    if n > 10 {
      return n.decomposed(n / 10)   [n % 10] 
    } else {
      return [n]
    }
  }
}

This is the part, however, in which it gets trickier. I'm being told by the compiler that error: cannot find 'self' in scope.

Having read about the methods in the docs, I've resorted to using Int? default argument. Now, the extension is implemented as:

extension Int {
  func decomposed(_ n: Int? = nil) -> [Int] {
    var _n = n ?? self
    if _n > 10 {
      return _n.decomposed(_n / 10)   [_n % 10] 
    } else {
      return [_n]
    }
  }
}

I don't like the look of the _n, though.
I would love to use self as the default argument. Is that possible? Or are we stuck with hackity hacks until the judgement day?

CodePudding user response:

Wrote a quick implementation to highlight the usage of extensions:

import Foundation

func main() {
  print(2.test()) // prints 2
  print(12.test()) // prints 3
  print(42.test()) // prints 6
}

extension Int {
  func test() -> Int {
    if self <= 10 {
      return self
    }
    return (self % 10)   (self/10).test();
  }
}

main()

You don't need to pass self as an argument, since that will not work. By default, self will be available for use inside the extension methods (since that follows the object oriented paradigm).

CodePudding user response:

You need to remove n as a parameter, replace every use of n in the function with self (since that's what's being operated on), and convert the function syntax to the method syntax in the recursion:

extension Int {
    func decomposed() -> [Int] {
        if self > 10 {
            return (self / 10).decomposed()   [self % 10]
        } else {
            return [self]
        }
    }
}
  • Related