Swift cast protocol type to struct and pass as inout

2k Views Asked by At
protocol ValueHolder {
}

struct A: ValueHolder {
    var value = 5
}

var x: ValueHolder = A()

func f(a: inout A) {
    a.value = 10
}

I want to use pass x to f. Is it possible?

Edit: I understand all of the staff about value semantics and inout parameters. The problem is that x needs to be casted to A and I wonder if that can be done without copying it (as makes a typed copy of it) so that I can use f on x.

1

There are 1 best solutions below

10
On BEST ANSWER

I want to use pass x (and not its copy) to f. Is it possible?

Not exactly — at least, not if the parameter is an A. An A is a struct. Even with inout, a struct is still a value type. inout allows the original value to be replaced, but what it is replaced with is another A. Simply put, a struct cannot be mutated in place.

That being so, your question seems to lose its meaning. Since a struct cannot be mutated in place, there is no real reason to use inout here at all. You are not doing anything that calls for inout. You might as well just drop the inout and accept the value semantics:

func f(a: A) -> A {
    var a = a
    a.value = 10
    return a
}
x = f(a:x as! A)

If you really want to keep the inout, then type a: as a ValueHolder and cast inside the function, like this:

var x: ValueHolder = A()
func f(a: inout ValueHolder) {
    var b = a as! A
    b.value = 10
    a = b
}
f(a:&x)
(x as! A).value // 10