简体   繁体   中英

Swift: Updating struct variables?

I'm fairly new to Swift, and I've stumbled across this problem today which will help me a lot if answered. The code below explains my issue:

struct Foo {
  var x: Float
  mutating func change() {
    x += 1
  }
}

struct Bar {
  var y: Float
}

var foo = Foo(x: 1)
let bar = Bar(y: foo.x)

foo.change()

print(foo.x) // 2.0
print(bar.y) // 1.0 (how can I make this 2.0 as well?)

I thought I might have to use pointers but I have no idea how to, and I have no clue if that'd even work. Any ideas will help!

One way to get what you want here is to define Bar to keep a reference to Foo . And since you want a change to an instance of Foo to carry over to the reference held by a Bar , you would need to make Foo a class instead of a struct.

Here's one possible solution:

class Foo {
    var x: Float

    init(x: Float) {
        self.x = x
    }

    func change() {
        x += 1
    }
}

struct Bar {
    var foo : Foo
    var y : Float { return foo.x }

    init(foo: Foo) {
        self.foo = foo
    }
}

var foo = Foo(x: 1)
let bar = Bar(foo: foo)

foo.change()

print(foo.x) // 2.0
print(bar.y) // 2.0 as asked

When you write

let bar = Bar(y: foo.x)

the value foo.x ( 1 ) is copied inside Bar .

So doesn't exist no further connection between foo.x and bar.x .

This happens because in Swift params are passed by value.

Solution

First of all we need a generic wrapper

class Wrapper<Element> {
    var element: Element
    init(element: Element) {
        self.element = element
    }
}

now we can redefine Foo and Bar

struct Foo {
    var x: Wrapper<Float>
    mutating func change() {
        x.element += 1
    }
}

struct Bar {
    var y: Wrapper<Float>
}

As you can see now Foo and Bar doesn't hold the Float value but a reference to a Float value. We will use this to make the foo and bar value to reference the same Float value.

Finally we can test that the value is changed across both structures

var foo = Foo(x: Wrapper<Float>(element: 1))
let bar = Bar(y: foo.x)
foo.change()

print(foo.x.element) // prints 2.0
print(bar.y.element) // prints 2.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM