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?
Vector2 an immutable struct?Response to 1: No, it is not immutable; I think you proved it yourself
Response to 2: Pretty sure your question is a contradiction; one cannot modify an immutable object
Response to 3: Immutable objects are great if you have something you want to create, use it over and over again without modifying it, and then you're good to go. They are not appropriate if you want to create, use, modify, use again, modify again, etc. If you have a scenario where the thing is create/use-but-not-change/terminate, then making it immutable is a good thing because you KNOW it hasn't been edited-behind-your-back... you can trust him like a rock on his code. This is not suitable for something you want/need to modify (eg the position of the rollerball). Therefore, Vector2 is ideal for that last case. It's not really about safe and unsafe, but about appropriate and inappropriate.
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)