I started Golang.
Golang uses pointers.
Since Golang is historically a new language, I thought that I could just write code without being aware of pointers and it would work fine, but I was naive...
The pointer itself is common, and if you pass it as a pointer anyway, you don't have to worry about manipulating the big source, When you pass it by value, you may have trouble knowing what to pass and what to do with it.
And in that area, I sometimes got into it because I made judgments based on my preconceptions and self-serving assumptions in other languages.
I will make a note here as a reminder, focusing on what I personally got into.
rehearsal
Review what is done when a function is passed an argument and receives a return value.
For example, let's look at a function that "returns a string with a formula that multiplies an integer by 100 when passed.
func test(x int) string { y := x * 100 s := fmt.Sprintf("%d x 100 = %d", x, y) return s } func main(){ a := 1 b := test(1) fmt.Println(b) // 「1 x 100 = 100」 }
Let's try to express this without functions to show what is going on inside.
func main(){ a := 1 // function start x := a // Capturing Arguments y := x * 100 s := fmt.Sprintf("%d x 100 = %d", x) b := s // Return value // end of function fmt.Println(b) }
The point is that the "=
" assignment is made when passing arguments to the function and when receiving the return value from the function.
In other words, once you know what is done with the "=
" assignment, you know what is passed to and returned from the function.
Behavior of "=" and "=="
In the case of int
Assignments of basic types such as int are copied.
Comparisons are made by looking at values, not entities.
a := 1 b := a fmt.Println(a) // 1 fmt.Println(b) // 1 fmt.Println(a == b) // true b = 2 fmt.Println(a) // 1 fmt.Println(b) // 2 fmt.Println(a == b) // false
For arrays
Unlike C, Golang's array assignments are copied.
Comparisons are made by looking at values, not entities.
a := [2]int{1, 1} b := a fmt.Println(a) // [1 1] fmt.Println(b) // [1 1] fmt.Println(a == b) // true b[0] = 2 fmt.Println(a) // [1 1] fmt.Println(b) // [0 1] fmt.Println(a == b) // false
In the case of a structure
Golang's structure assignments are copied, just as in C.
Comparisons are made by looking at values, not entities.
type myStruct struct { x int } a := myStruct{x: 1} b := a fmt.Println(a) // {1} fmt.Println(b) // {1} fmt.Println(a == b) // true b.x = 2 fmt.Println(a) // {1} fmt.Println(b) // {2} fmt.Println(a == b) // false
Slice map string (string)
I'll just conclude here.
- Slice string is the same as structure
- Maps are the same as pointers
We think in terms of
But what is a "slice map string" anyway? But since this is a long story, we have summarized it in a separate article.
Note on "=" and "==" behavior
In summary, Golang's assignments and comparisons have the following characteristics
- Array assignment is a copy and the value is also copied
- Array comparison compares values in an array
- Assigning a structure is a copy, and the value is also copied.
- Structure comparisons compare values within a structure.
- Variables are always initialized with the initial value.
This may seem like a small difference when compared to the C language, but this specification makes coding a heck of a lot easier!
Large arrays and structures are passed using pointers.
As mentioned earlier, array and structure assignments are copies, so when exchanging large arrays and structures with functions, it is better to pass them by pointer.
type myStruct struct { x [100000]int } // cross-valued func testObject(v [100000]int) myStruct { // Array is copied when v is created o := myStruct{ x: v, // Copying the array here is not an option. } return o // When returning a value, a copy of the structure (a copy of the array of elements) is made } // pointer overlay func testPointer(v *[100000]int) *myStruct { o := new(myStruct) o.x = (*v) // Copying the array here is not an option. return o }
new()
Golang also has an new()
function like the C++ language.
It behaves as you might expect, creating a memory area of the specified type and returning a pointer. The value is also initialized.
a := new(int) fmt.Println(*a) // 0 *a = 123 fmt.Println(*a) // 123
However, Golang does not have a "Local variables can be used instead of new()
There is a super-convenient specification called "the "I" specification," which you may use more often.
For example, the aforementioned testPointer()
can be written as follows in Golang.
func testPointer(v *[100000]int) *myStruct { o := myStruct{ x: *v, } return &o // Passing the address of a local variable is not a problem. }
Impressions, etc.
Once you have the assignment down, you know what is exchanged in the function, and it is easier to consider whether it is better to pass a value or a pointer to the function.
As noted in the article below, Golang rarely uses map strings as pointers.
Also, when we want to use arrays, we use slices instead, and there are few situations where we deal directly with arrays themselves.
Then, the places to consider whether to pass values or pointers are mainly where structures or slices are exchanged.