NB: Set aside any functional programming principles for the sake of this example.
How things work in JavaScript
When you pass an object
into a function, the function receives the instance of that object
, meaning that the function body can directly mutate that very same object
. Put differently, JavaScript passes a reference to that object
rather than a copy of its value.
const sample = {
one: "Original value",
two: "Original value"
};
console.log(sample); // Logs: {one: "Original value", two: "Original value"}
mutate(sample);
console.log(sample); // Logs: {one: "Original value", two: "New value"} --> Mutated
function mutate(s) {
s.two = "New value";
}
How things work in Go
When you pass an object
(or instance of a struct
in Go parlance), the function receives a copy of that object
, meaning that the function body cannot directly mutate that very same object
. In other words, Go passes a copy of that object
's value rather than a reference to it. (Run this example yourself here.)
package main
import (
"fmt"
)
type sample struct {
one string
two string
}
fun main() {
s := sample {
one: "Original value",
two: "Original value",
}
fmt.Printf("%+v", s) // Logs: {one:Original value two:Original value}
mutate(s)
fmt.Printf("%+v", s) // Logs: {one:Original value two:Original value} --> Not mutated
}
func mutate(s sample) {
s.two = "New value"
}
How to make Go behave like JavaScript
It is possible to pass a reference to an object
(i.e., struct
) in Go that then allows for direct mutation of that same object
, but it must be done explicitly. That is, you must pass a pointer
(or reference
) to the object
that is passed into the function. (Run this example yourself here.)
package main
import (
"fmt"
)
type sample struct {
one string
two string
}
func main() {
s := sample {
one: "Original value",
two: "Original value",
}
fmt.Printf("%+v", s) // Logs: {one:Original value two:Original value}
mutate(&s)
fmt.Printf("%+v", s) // Logs: {one:Original value two:New value} --> Mutated
}
func mutate(s *sample) {
s.two = "New value"
}