1

For my grid-system (2D-array) I'm creating a Index2-struct. Which is very similar to a Vector2.

Running into some issues I read up on structs. Coming across the mutable and immutable subjects.

Long story short, mutable structs are bad. So then I wondered, how would I make my struct immutable? Which led me to this post.

If understood correctly, to make a struct immutable you have to make sure once the instance is created, the members of the instance cannot be modified.

But then when I look at the Vector2-struct in unity. Once you have created a new Vector2(0f, 0f), you cán modify its values:

Vector2 myVector = new Vector2(1f, 1f);
myVector.x = 2f;

This works just fine.

Same with the .Set-method:

Vector2 myVector = new Vector2(1f, 1f);
myVector.Set(2f, 2f);

Also looking at the definition of a Vector, I dont see any of the solutions suggested in the above linked post.

Which makes me wonder a couple of things?

  1. Is a Vector2 an immutable struct?
  2. If it is, how is it structured to be still immutable while being able to modify members?
  3. If it is not, why is it still a safe struct to use?
Vrt
  • 19
  • 1
  • Here's a similar question about another Vector struct being mutable. https://stackoverflow.com/questions/8920080/why-are-system-windows-point-system-windows-vector-mutable – juharr Mar 26 '21 at 15:23
  • For the sake of completeness, here's the `Vector2` source: https://github.com/Unity-Technologies/UnityCsReference/blob/2020.2.0a13/Runtime/Export/Math/Vector2.cs – galdin Mar 26 '21 at 15:31
  • its not .. but it's a struct which is assigned to a **property** (e.g. transform.position etc) then youc an't simply do `transform.position.x = ...` because this wouldn't call the setter of the property – derHugo Mar 26 '21 at 16:21
  • What do you mean by "a safe struct"? – Ruzihm Mar 26 '21 at 21:01
  • Reading about mutable structs I got the impression that they're not safe to use, as in, they can cause problems in your project. I concluded the vector2-struct was a mutable struct, but is also a default struct of unity. I cant imagine they would include a struct that would cause problems in your project. Maybe the questions weren't really clear. But my thinking was, even though Vector2 is a mutable-struct, maybe in the background its structured in such a way that it wont cause any problems a custom mutable struct would. And if so, I could apply that to my Index2. – Vrt Mar 27 '21 at 01:29
  • Also, apparently. This question was already asked before, as mentioned above. Nothing showed up when I searched for it. – Vrt Mar 27 '21 at 01:34

3 Answers3

1

Answer to 1: No, it is not immutable; I think you proved that yourself

Answer to 2: Pretty sure your question is a contradiction; one cannot modify an immutable object

Answer to 3: Immutable objects are great if you have something you wish to create, use again and again without ever altering and then you are done. They are not appropriate if you want to create, use, alter, use again, alter again, and so on. If you have a scenario where the thing is create/use-but-do-not-change/finished then making it immutable is a good thing because you KNOW that it hasn't been edited-behind-your-back ... it can be relied on like a rock in your code. This is not suitable for something you want-to/need-to alter (e.g., position of rolling ball). Vector2 is therefore ideal for that last case. It's not really about safe and unsafe but appropriate and inappropriate

Neil Gatenby
  • 419
  • 6
  • 21
  • `Vector2` isn't an "object" (unless you box it), so "immutable objects" may be a false comparison; when talking about a position - I would say that when you change a position, you logically don't change *a feature of a position*, but rather: you change the entire position to a *different position value* - the fact that a position value is composed of x/y/z (or whatever) is irrelevant; I would counter that **immutable** value-types are *perfect* for "position" types, just: you'd do `obj.Position = obj.Position.Add(3, 0, 42);` or whatever – Marc Gravell Mar 26 '21 at 15:33
  • Interesting stuff @MarcGravell. Thanks – Neil Gatenby Mar 30 '21 at 09:58
1

Its not immutable. Most people havint issues with not being able to modify individual components of Vector3 do something like

transform.position.x=value;

this will not work, but not for the reason of immutability. This will not work, because transform.position is not actually a field, its a property (getter setter pair). In hardly anything that Unity3D exposes, is setters/getters, so its defined not as

public Vector3 position;

but as three seperate elements, a backing field, and a parir of methods run to retrieve or set the value, so (I am calling my property pos not position not to confuse with actual Transform implementatoin wchich is waay more complex).

private Vector3 _pos;
public Vector3 pos { get { return _pos;} set  { _pos=value;}}

Now here's the trick. Properties are essentially just syntax sugar in C#, so under the hood this compiles to something like

private Vector3 _pos;
public Vector3 GetPos () 
   { return _pos; } 
public void SetPos(Vector3 value) 
   {  _pos=value;}}

Now if you look closely at statements like

  transform.position.x+=1;  // won't work

They dont make sense, because what you actually mean by that is :

Vector3 temp = transform.GetPos();
temp.x+=1; // Vectors3 mutate all right
transform.SetPos(temp);

Because .position is a property, and has a backing method, it has to execute and return a full struct, before you can modify and send a new one in. If position was a field, this would be fine, but transform would have no way to know it has changed and apply your change (and it does need to do surptisingly lot of math if you set global position)

Dharman
  • 30,962
  • 25
  • 85
  • 135
zambari
  • 4,797
  • 1
  • 12
  • 22
0
  1. no, it is mutable
  2. it isn't
  3. it isn't; all the ways that mutable structs can cause problems very much apply; so: just be careful
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Re #3: the idea that mutable structures are "unsafe" is very much overstated. There are some pitfalls. These are very minor compared to all the potential sources of bugs. – Ben Voigt Mar 26 '21 at 15:29
  • @BenVoigt indeed, but the problem is that *to the outsider* the risky uses look entirely reasonable; if you know what not to do, they can absolutely be used "safely" – Marc Gravell Mar 26 '21 at 15:30