I started Golang.
When I started, I found that Golang is designed to be as simple as possible in its syntax and as simple in its code as possible.
And for that reason, Golang has some slightly tricky syntax.
However, without knowing them, I made judgments based on my preconceptions and self-serving assumptions in other languages, and got into a bit of trouble.
Here, I would like to note down some of the things that I personally got into or misunderstood when I started Golang, as a reminder by topic.
In this issue, a note on pointer operators.
Missing pointer arrow operator
Golang has pointers.
As in the C language (C++ language, hereafter referred to as C), the &
operator is used to obtain an object address. As in the C language (C++ language, hereafter referred to as C), the &
operator is used to obtain the address of an object.
To reference an object from a pointer, use the "*
" operator as in the C language.
However, in C, to access an object's member variables/functions from an object, you use the ".
" operator, and to access an object's member variables/functions from an object's pointer, you use the "->
" (arrow) operator,
While the ->
(arrow) operator is used to access an object's member variables/functions from the object's pointer,
Golang uses the .
operator in both cases.
Example: Either object pointer ". can be accessed with
package main import "fmt" type myStruct struct { x int } func (o myStruct) testObject() { fmt.Println("Object") } func (p *myStruct) testPointer() { fmt.Println("Pointer") } func main() { // object var a myStruct a.testObject() // Object a.testPointer() // Pointer fmt.Println(a.x) // 0 // pointer b := &a b.testObject() // Object b.testPointer() // Pointer fmt.Println(b.x) // 0 }
The ".
" operator in Golang is more like a statement of intent to access a member variable/function than an operator.
The compiler will decide whether the original variable is an object or a pointer and give you access to the member variable/function as it sees fit,
Don't worry about the details, just use the ".
" operator.
It is like that.
What happens if an object and a pointer have duplicate member functions?
The compiler does the object/pointer conversion automatically, but when there are two patterns of member functions, one where the caller is an object and the other where the caller is a pointer, Which member function is called?
As it turns out, functions with the same name cannot be defined, so there is no duplication.
For example, as shown below, an attempt to create a member function "test()" with the same name in an object and pointer will result in a compile error.
package main import "fmt" type myStruct struct { x int } func (o myStruct) test() { fmt.Println("Object") } func (p *myStruct) test() { fmt.Println("Pointer") } func main() { var a myStruct a.test() b := &a b.test() }
In other words, I knew it.
Don't worry about it, just use the ".
" operator.
It is.
Difference between a member function of an object and a member function of a pointer
There are two ways to write member functions of a structure: in an object or in a pointer.
At a quick glance, they look the same, but in the case of objects, when a structure is passed to a function, a copy of the structure is created and operations are performed on that copy.
In the case of pointers, on the other hand, the function is passed a pointer to the structure, so the operation is performed on the actual state of the structure.
What is different as a result is that in the case of a pointer, the value of an element of the structure can be changed from the function, but in the case of an object, the value of the element of the copy of the structure is changed and the value of the element of the original structure remains the original.
package main import "fmt" type myStruct struct { x int y int } // I want to change x func (o myStruct) testX(v int) { // o is a copy of the calling structure o.x = v } // I want to change y func (p *myStruct) testY(v int) { // p is the pointer to the calling structure p.y = v } func main() { a := myStruct{x:1, y:1} fmt.Printf("%+v\n", a) // {x:1 y:1} a.testX(2) // The x in a is unchanged. a.testY(2) // The y in a is changed fmt.Printf("%+v\n", a) // {x:1 y:2} }
My personal opinion is that there are few cases where I would not want my elements to be changed by member functions; rather, it is likely that misunderstanding mistakes will be made due to the specification that cannot be changed from member functions. Also, I wonder if we will mainly use pointers because of the cost of copying structures.
If you want to perform immutable operations that do not change the value of the original structure, it would be better to have a separate function that explicitly passes an object as an argument.
Only member variables/functions can be good
The automatic conversion of object pointers is done only for member variables and functions, not for ordinary functions.
package main import "fmt" type myStruct struct { x int } func test(o myStruct) { fmt.Println("Object") } func main() { var a myStruct test(a) // Object b := &a test(b) // error }
So I wonder if these series of specifications are easier to understand if ".
" is interpreted as a member access operator rather than an automatic object pointer conversion.
Impressions, etc.
This specification makes the program cleaner.
However, although it is reasonable, some of it is a bit of a blur, since it means that the operator behaves differently in different situations.
Well, that may be a matter of familiarity.