TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Passing a class reference from a list of classes isn't updating as expected

Forums > Swift

I have a function I apply to a bunch of large arrays of numerical data. This function changes the data in the firstParticles class and works:

private func rule(firstParticles: inout Particles, secondParticles: Particles, grav:Float){
...
}

The following ugly code works to apply the rule function to four particle structs I am tracking:

        rule(firstParticles: &redParticles, secondParticles: redParticles, grav: gravs[0][0])
        rule(firstParticles: &redParticles, secondParticles: whiteParticles, grav: gravs[0][1])
        rule(firstParticles: &redParticles, secondParticles: blueParticles, grav: gravs[0][2])
        rule(firstParticles: &redParticles, secondParticles: greenParticles, grav: gravs[0][3])

        rule(firstParticles: &whiteParticles, secondParticles: whiteParticles, grav: gravs[1][1])
        rule(firstParticles: &whiteParticles, secondParticles: redParticles, grav: gravs[1][0])
        rule(firstParticles: &whiteParticles, secondParticles: blueParticles, grav: gravs[1][2])
        rule(firstParticles: &whiteParticles, secondParticles: greenParticles, grav: gravs[1][3])

        rule(firstParticles: &blueParticles, secondParticles: blueParticles, grav: gravs[2][2])
        rule(firstParticles: &greenParticles, secondParticles: greenParticles, grav: gravs[3][3])
        rule(firstParticles: &blueParticles, secondParticles: whiteParticles, grav: gravs[2][1])
        rule(firstParticles: &blueParticles, secondParticles: greenParticles, grav: gravs[2][3])

        rule(firstParticles: &blueParticles, secondParticles: redParticles, grav: gravs[2][0])
        rule(firstParticles: &greenParticles, secondParticles: redParticles, grav: gravs[3][0])
        rule(firstParticles: &greenParticles, secondParticles: whiteParticles, grav: gravs[3][1])
        rule(firstParticles: &greenParticles, secondParticles: blueParticles, grav: gravs[3][2])

But I hate it, and I want to clean it up. So I made a list of the four "Particle" structs I am using:

        var particleList = [redParticles, whiteParticles, blueParticles, greenParticles]

and looped over it passing the first one by reference and the second's by value since it is never modified (gravs is a matrix of values):


        for first in 0 ..< 4{
            for second in 0 ..< 4 {
                rule(firstParticles: &particleList[first], secondParticles: particleList[second], grav: gravs[first][second])
            }
        }

Which builds fine and runs with no complaints, but does not actually update the firstParticles list. They seem like they should be equivalent. I am pretty new to Swift (this is actually my first Swift project) and cannot tell if this is some subtely of the language I am missing.

   

OK, so I got it working, and sort of understand why, but don't like it. The problem was that I created each Particle struct then made the list from those items, like this:

var red:  =Particle( *initializer stuff here*)
var white:  =Particle( *initializer stuff here*)
var blue:  =Particle( *initializer stuff here*)
var green:  =Particle( *initializer stuff here*)

var particleList = [red, white, blue, green]

when I changed it to initializing the structs in the creation of the list, everything worked:

var particleList = [Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*)]

So now I understand that the original list made its own weak copies of the structs and when I passed those to the function it wasn't really operating on the originals.

But is there a way to tell swift I really want to pass something by reference and mutate it becuase it is really big and I don't want it copied all over the place?

I this case I am working with several thousand particles and I don't want the handholding that swift is "helping" me with.

Or am I really something really big and there is a fundamentally different way to handle this.

   

OK, so I got it working, and sort of understand why, but don't like it. The problem was that I created each Particle struct then made the list from those items, like this:

var red:  =c
var white:  =Particle( *initializer stuff here*)
var blue:  =Particle( *initializer stuff here*)
var green:  =Particle( *initializer stuff here*)

var particleList = [red, white, blue, green]

when I changed it to initializing the structs in the creation of the list, everything worked:

var particleList = [Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*),
                                Particle( *initializer stuff here*)]

So now I understand that the original list made its own weak copies of the structs when when I passed those to the function the function wasn't really operating on the originals.

But is there a way to tell swift I really want to pass something by reference and mutate it becuase it is really big and I don't want it copied all over the place?

I ths case I am working with several thousand particles and I don't wan the handholding that swift is "helping" me with.

Or am I really something really big and there is a fundamentally different way to handle this.

   

now for some more irritation, this works:

 for n in 0 ..< 4 {
            randomizeParticles(&particleList[n])
        }

but, this doesn't:

    for p in particleList {
            randomizeParticles(&p)
        }

Have years of C/C++ and Lisp spoiled me? I really like the swiftui way of working with UI, but there is a lot more to life than a pretty front end..

   

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.