Why doesn't inout pass by reference?
Asked Answered
W

2

2

I'm doing something like this:

someFunction(&myClass)

where someFunction sorts an array on myClass.

someFunction(inout someclass:ClassA) {
 someClass.sort({$0.price > $1.price})  
}

If I print myClass after the function call, I notice the array is still unsorted. From what I know, Swift passes values by copy. But when I use inout, shouldn't it change to pass by reference?

Wheezy answered 1/10, 2015 at 4:58 Comment(6)
Can you show a (small) complete, self contained example?Severalty
That's exactly what it's doing: #30541744Glorygloryofthesnow
I posted some additional code. @snowman4415's answer makes sense. I tested and that is the case. I'm actually doing a sort() on an array.Wheezy
Also note that if you actually were sorting on a class and not an array, you would not need the inout, as inout is only for assigning a new value to someclass and not modifying it in place. Conversely, if you were sorting on a struct (likely), you could assign the result to the inout param to get the desired effect.Farfamed
Could you mark answer if you find one satisfactory?Malta
Everyone's just telling him what he already knows. He's not asking the difference between reference and value types. He's asking why "inout" does not produce the same results as explicitly passing a pointer as a parameter to the function. Explicitly passing a POINTER to a value type.Gracegraceful
M
4

This is because class instances and functions are reference types. Ints, structs, and everything else are value types. When you pass a reference type into a function as a parameter, you are already going to be referencing that instance. When you pass a value type as a parameter, the function gets a copy of that variable (by default), so inout is usually (see edit) only needed if you want to alter a value type from inside of a function.

Altering a class instance without & or inout:

enter image description here

More details

When you create a reference type var t = myClass(), you're really creating a variable t that is a pointer to a myClass instance in memory. By using an ampersand &t in front of a reference type, you are really saying "give me the pointer to the pointer of a myClass instance"

More info on reference vs value types: https://mcmap.net/q/166149/-is-swift-pass-by-value-or-pass-by-reference

EDIT

As was pointed out in the comments, you can still use inout with reference types if you want to alter a pointer, etc, but I was trying to shed light on the general use case.

Below is an example of sorting an array inside of a function:

enter image description here

Malta answered 1/10, 2015 at 5:14 Comment(4)
"so inout is needed only if you want to alter a value type from inside of a function." Not true, you need inout with reference types if you want to alter a reference -- i.e. if you want to change it to point to another object. Of course, all reference types are "value types", where the only value is a reference, so technically your statement is correct, but then it would be a trivial statement so that's probably not what you meant.Fendley
@snowman4415: I tested and that is the case. I'm actually doing a sort() on an array. I don't see the sorted values when I reference the class after and outside of the function call.Wheezy
@Wheezy check out my edit. sort does not alter the array in place, you need to reassign the return value.Malta
Please put code examples as text instead of images. Better for copying the code for anyone to try.Unplaced

© 2022 - 2024 — McMap. All rights reserved.