In Google Go, I read that Strings are immutable, ok but are int's? What about other types? As a slightly older programmer I prefer mutability even though I know the benefits of immutability, I prefer to live dangerously.
Know what types are mutable or immutable would be very helpful.
Update, what I am mostly concerned about is the practical issues depending upon the type being mutable or immutable. As in the typical example in Java, if you create a String in a loop and loop for 10,000 times, you will get 10,000 String's created which are then later garbage collected. This has actually been a serious issue in a project in a company I worked at.
The the question is, does Go's Immutability in some cases cause the same problem?
It affects how you should treat the var. (or I assume it does).
Update again, I am also concerned about other practical concerns. Knowing that something is immutable means that I can write code which is parallel and updates to one reference of the object should not update the other references. However sometimes I wish to do dangerous things, I want mutability.
These are consequences of mutability vs immutability and affect how I can write the code.
Don't worry -- Go will let you shoot yourself in the foot if you really want to :-)
Go is not like Erlang, which might be what you are getting at with the question.
x := 1
x = 2
allocates one variable, x
, with a value of 1
, then reassigns it to 2
-- no additional memory is allocated here.
As you note, strings are immutable, so doing a string manipulation can result in making copies. If you find that you want to do in-place modifications to character data, you'll probably want to operate on variables of []byte
via the bytes
package.
Russ Cox's post about this should answer most of your questions about basic data structures: http://research.swtch.com/2009/11/go-data-structures.html
As other commenters noted, you'll want to look at the value semantics of Go functions -- they might be a little surprising at first.
If you have the following function:
func (t MyType) myFunc() {
// do something to set a field in t
}
and you call in your code
myVar.myFunc()
you might be surprised to see that this doesn't do what you want because the t
that is seen in myFunc()
is really a copy of myVar
.
But, the following will work:
func (t *myType) myFunc() {
// do something to set a field in t
}
because the function has a copy of the pointer and can access the underlying structure via that pointer.