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.
This time, a note about the "cannot assign to struct field ..." error when putting a struct into a map. error when inserting a struct into a map.
Cannot be assigned to an element of a structure stored in a map
The map can contain structures, but if you try to assign (=
) to an element of the structure
cannot assign to struct field ...
I get an error saying "I can't do it.
The code is as follows.
package main type myStruct struct { x int } func main(){ a := make(map[int]myStruct) a[0] = myStruct{x: 0} // Cannot do it due to compile error. a[0].x = 1 // cannot assign to struct field a[0].x in map }
This is troubling...
Let's look at some other cases.
Assignments to structures stored in a map can be made.
Naturally, you can assign the entire structure to elements of the map.
package main type myStruct struct { x int } func main(){ a := make(map[int]myStruct) a[0] = myStruct{x: 0} // I can do this. a[0] = myStruct[x: 1} }
The value of the element of the structure stored in the map can be retrieved.
Retrieving the value of an element of a structure is not a problem.
package main type myStruct struct { x int } func main(){ a := make(map[int]myStruct) a[0] = myStruct{x: 0} // I can do this. if 0 == a[0].x { fmt.Println(a[0].x) // 0 } }
Calling methods of structures stored in the map
method can be called for objects, but it will result in a compile error for pointers.
package main type myStruct struct { x int } func (o myStruct) object(){ fmt.Println(o.x) } func (p *myStruct) pointer(){ fmt.Println(p.x) } func main(){ a := make(map[int]myStruct) a[0] = myStruct{x: 0} // I can do this. a[0].object() // 0 // This can't be done due to a compile error. a[0].pointer() // cannot take the address of a[0] }
This is due to the difference in the behavior of the pointer, which attempts to manipulate the structure directly via the address of the structure stored in the map, as opposed to the object, which copies the structure stored in the map and manipulates that structure when passing it to a function.
Causes and remedies
When an element (structure) stored in a map is retrieved, it is not the entity of the stored element (structure), as shown in the error "cannot take the address" when the pointer's method is called.
So, although you can get the value of the element you extracted, you cannot change or manipulate the element's internals.
It is possible to replace an entire element with a new one using the "=
" operator, or to delete the element itself using the "delete()
" function.
These behaviors are Golang specifications, so we have no choice but to accept them. If we want to change the value of a structure, as in the example above, we have to replace the entire structure with a new one.
However, if the structure is huge, it is expensive to copy and replace the structure every time, so I think it would be better to deal with this by having the map store pointers to the structure instead of storing the structure itself.
The code is as follows.
package main // Huge structure type myStruct struct { x int array [10000]int } func main(){ // Stores a pointer without a structure entity. a := make(map[int]*myStruct) a[0] = &myStruct{x: 0} // I can do this. a[0].x = 1 fmt.Println(a[0].x) // 1 }
Impressions, etc.
I heard that Golang was simple, and I started with a light heart, wondering if I could program in some kind of atmosphere, but I am constantly reminded of whether it is an entity or a pointer.
Reference Articles
- https://www.pospome.work/entry/2017/02/01/015856
- https://qiita.com/Fukku/items/f5aa19d2bcae617e93fb
- https://qiita.com/souring001/items/ac56467e21d4db877a39