5

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
  • 123,697
  • 21
  • 207
  • 260
Brandon Bradley
  • 2,720
  • 4
  • 19
  • 38

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,326
  • 25
  • 33
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
  • 634
  • 6
  • 16
1

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
  • 14,647
  • 5
  • 57
  • 94
  • 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,412
  • 6
  • 25
  • 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