kusumoto_teruya
kusumoto_teruya

Reputation: 2475

Pass a variable reference to a instance property

I want to make sure that if you update the original variable, the instance property is also updated.

class Sample {

    var number: Int
    
    init(number: inout Int) {
        self.number = number
    }
}

var number = 0
let sample = Sample(number: &number)

number = 1
print(sample.number)    // 0

In the above code, the instance property has not been updated.
How do I fix it?

Upvotes: 0

Views: 127

Answers (1)

Sweeper
Sweeper

Reputation: 270860

inout parameters work like this (source):

  1. When the function is called, the value of the argument is copied.
  2. In the body of the function, the copy is modified.
  3. When the function returns, the copy’s value is assigned to the original argument.

This is not "pass by reference" in the C or C++ sense. You are not passing a "reference" to the initialiser. The compiler can optimise inout parameters to use the same memory address for both the original and the copy, but at that point, you know too much :)

So what you are trying to do doesn't really make sense. You seem to want Sample.number to store a "reference" to the Int that you passed in, but that's not possible, because Int is a value type.

You have to make your own wrapper class for Int:

class IntWrapper : ExpressibleByIntegerLiteral, CustomStringConvertible {
    var wrapped: Int
    
    required init(integerLiteral value: Int) {
        wrapped = value
    }
    
    var description: String { wrapped.description }
}

class Sample {

    let number: IntWrapper
    
    init(number: IntWrapper) {
        self.number = number
    }
}

let number: IntWrapper = 0
let sample = Sample(number: number)

number.wrapped = 1
print(sample.number)

Upvotes: 1

Related Questions