Reputation: 6892
Having this:
struct Person {
var name = "Noname"
}
class World {
var person: Person!
func changePersonName(newName: String) {
person.name = newName
}
}
let you = Person(name: "Adam")
let world = World()
world.person = you
world.changePersonName("Eve")
println(you.name) // not "Eve", still "Adam"
In my case, I want person.name
to become "Eve".
My question is how do I make the person
variable in World
not a copy, but a reference that I can modify its value like an object reference?
Upvotes: 0
Views: 183
Reputation: 4605
As s1ddok pointed out, you can use UnsafeMutablePointer
:
struct Person {
var name = "Noname"
}
class World {
var person: UnsafeMutablePointer<Person>!
func changePersonName(newName: String) {
person.memory.name = newName
}
}
var you = Person(name: "Adam")
var ptr = UnsafeMutablePointer<Person>.alloc(1)
ptr.initialize(you)
let world = World()
world.person = ptr
world.changePersonName("Eve")
print(ptr.memory.name)
Upvotes: 0
Reputation: 535989
As GoZoner has rightly said, if you want to have a side-effect of mutating a Person through some other reference, you need a class, not a struct. That is exactly one of the chief differences between a class and struct. A struct is a value type; a class is a reference type. Thus, starting with your example code and fixing it so that it actually compiles:
struct Person {
var name = "Noname"
}
class World {
var person: Person!
func changePersonName(newName: String) {
person.name = newName
}
}
let you = Person(name: "Adam")
let world = World()
world.person = you
world.changePersonName("Eve")
print(you.name) // "Adam"
print(world.person.name) // "Eve"
So, you can see that you
and world.person
are two different instances of Person. They are not references to one and the same instance. That's usually regarded as a good thing, but if, for some reason, that's not what you want, then use a class:
class Person {
var name = "Noname"
init(name:String) {self.name = name}
}
class World {
var person: Person!
func changePersonName(newName: String) {
person.name = newName
}
}
let you = Person(name: "Adam")
let world = World()
world.person = you
world.changePersonName("Eve")
print(you.name) // "Eve"
print(world.person.name) // "Eve"
Upvotes: 1
Reputation: 4654
If you really want to have a reference to a struct then UnsafeMutablePointer
is your choice, but I wouldn't recommend using it.
Upvotes: 0
Reputation: 70235
If you want a 'reference type', rather than a 'value type', then use a class
, rather than a struct
.
class Person {
var name = "Noname"
}
class World {
var person = Person()
changePersonName (name: String) {
person.name = name
}
}
Upvotes: 2