6

Assume the following:

class A {
    let x : Int
    init() {
        self.x = assign(1)
    }
    func assign(y : Int) -> Int {
        return y
    }
}

This produces an error.

Here is my question : is there a way to call functions within the class initializer?

EDIT: Added error message:

use of 'self' in method call 'assign' before all stored properties are initialized

Sulthan
  • 128,090
  • 22
  • 218
  • 270
Brandon Bradley
  • 3,160
  • 4
  • 22
  • 39

4 Answers4

3

You can't call instance methods until the instance is initialized (before init is done), but you can use module-level functions and type methods defined using the class or static keyword.

func compute(y: Int) -> Int {
  return y
}

class A {
  let x: Int

  static func assign(y: Int) -> Int {
    return y
  }

  init () {
    x = A.assign(3) + compute(4)
  }
}
szym
  • 5,606
  • 28
  • 34
3

One other (possibly helpful) option is to have the function you call within the initializer scope:

class A {
    let x : Int
    init() {
        func assign(y : Int) -> Int {
            return y
        }
        self.x = assign(y: 1)
    }
}

I'm doing that in a project right now. I have a large initializer (its actually a parser) and use an initializer-scoped function for error reporting. Of course, I'd prefer the function to be at class scope so I can reuse it between initializers. But at least I can reuse it within each initializer.

Darrell Root
  • 724
  • 8
  • 19
2

I think it is not the greatest solution but still it is working.

 class A {
        var variable : Int

        init() {

            self.variable = A.assign(1)

        }

        private class func assign(y : Int) -> Int {
            return y
        }
    }
Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100
  • It works, thanks. Out of curiosity, why does this work while the previous method did not? – Brandon Bradley Mar 25 '16 at 13:16
  • it is a class function and this kind of function do not need initialization of the object or @Sulthan could you deeply explain – Oleg Gordiichuk Mar 25 '16 at 13:19
  • I have a huge function that I would like to call from several init() methods. This huge function initializes several of the class properties. I have done as above, making this huge method a 'class' function, but I get an error on every property in the method. Of course, if I copy and paste this code into each init() method, it works. – Brian Reinhold Oct 02 '20 at 11:24
0

You could use somethings like:

class A {
    var x : Int!
    init() {
        x = assign(1)
    }
    func assign(y : Int) -> Int {
        return y
    }
}

The downside of this approach is that you will get a runtime error if you access x and it is not initialised. Check out this answer.

Community
  • 1
  • 1
Jelly
  • 4,522
  • 6
  • 26
  • 42
  • It works because now `x` is optional so the error doesn't apply anymore. Now you do not use `self` before all stored properties are initialised because you do not have such properties anymore, now they are optionals. – Jelly Mar 25 '16 at 14:00