I'm currently trying to learn GO and mainly knowing and working with Java, ASP.Net and some Python, there is no experience working with C-like pointers, which causes my current confusion.
A library I'm currently using to write my first GO project is called Commando.
There I have the struct CommandRegistry and the variable of interest is called Commands.
In the struct the variable is described as the following:
// registered command configurations
Commands map[string]*Command
On a first glimpse I would understand this as a Map object containing a list of Strings, however it also shows the pointer reference to the actual Command object.
All I can see is that it is a map I can loop over which returns the name of the command ( the string ),
however I'm wondering if the *Command in the type description means I can somehow dereference the pointer and retrieve the object itself to extract the additional information of it.
As I know the & operand is used to create a new pointer of another object. Pass-by-reference basically instead of pass-by-value.
And the * operand generally signals the object is a pointer or used to require a pointer in a new function.
Is there a way I can retrieve the Command object or why does the type contain the *Command in it's declaration?
Commands is a map (dictionary) which has strings as keys, and pointers to Commands as values. By passing it a key, you will get a pointer to the command it belongs to. You can then dereference the pointer to an actual Command object by using the * operator. Something like dereferencedCommand := *Commands["key"].
The * operator can be quite confusing, at least it was for me. When used as a type it denotes that we are receiving the memory address of some variable. But to dereference a memory address to a concrete type, you also use the * operator.
Related
This question already has answers here:
When to use pointers [duplicate]
(1 answer)
I don't understand when to use pointers on go [duplicate]
(2 answers)
Difference between returning a pointer and a value in initialization methods [duplicate]
(1 answer)
Pointers vs. values in parameters and return values
(5 answers)
Golang struct initialization
(2 answers)
Closed 15 days ago.
I am wondering what the differences are between those two ways of initializing a struct in Go. Does the second one give you a pointer storing the address of the struct? But they have the same syntax if we want to change the field variables, so how are they different?
I can de-reference the pointer, apparently. But do they have different functionalities? In what scenario would I prefer one over the other?
b := Student{Name:"Bob"}
pb := &Student{Name:"Bob", Age:8,}
They only differ in what the type of the local variable is. Whether to prefer one over the other depends entirely on how you would use that variable in the remainder of the function's body. If you are always passing it around (meaning use it on the right-hand side of an assignment, as an argument to a function call, or returning it) as a pointer, use the pb := &Student{...} form. If you intend to create (shallow) copies of it, the b := Student{...} form might be more convenient. This is however purely based on the fact that typing pb is easier than &b, and that typing b is easier than *pb. If you apply these substitutions everywhere (except for in the context of field accesses, where it is allowed but not mandatory, see below), they are completely interchangeable.
If you want to be able to set the variable holding the struct (pointer) to nil, use a pointer, obviously. But this can also be solved by introducing a new, pointer-typed variable and setting that to either nil or &b.
Some types in Go cannot be copied (this is typically accomplished by embedding a [0]sync.Mutex field in the struct, which takes up no space but triggers the "mutex copy" error of the compiler). An example would be protobuf structs. For these, it is almost always preferable to use the pointer form; however, this is not required, as the initialization via b := Student{...} is not a copy.
Go allows transparently dereferencing when accessing struct fields. b.Name, (&b).Name, pb.Name, (*pb).Name all work and are equivalent. Note however that transparent dereferencing only works over one level, (&pb).Name will result in a compiler error.
The composite literals differ in the initialization of the Age field. The first sets the field to the zero value. The second sets the field to the number 8. Otherwise, the initialization of the struct values is identical.
What happens next is where the key difference lies. The first example assigns the value to a variable named b. The second example takes assigns the value to an anonymous variable; takes the address of the variable; and assigns the result to a variable named pb.
The type of b is the struct type and the type of pb is a pointer to the struct type.
See I don't understand when to use pointers on go to see a discussion on why one might want to use a pointer.
Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true
Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true
How a object should be created for a struct?
object := new(struct)
or
var object struct
I could not understatnd when to use what? and if both are same which one should be prefered?
The new syntax you're showing returns a pointer while the other one is a value. Check out this article here; https://golang.org/doc/effective_go.html#allocation_new
There's actually even one other option which I prefer. It's called composite literal and looks like this;
object := &struct{}
The example above is equivalent to your use of new. The cool thing about it is you can specify values for any property in struct within the brackets there.
When to use what is a decision you need to make on a case by case basis. In Go there are several reasons I would want one or the other; Perhaps only the pointer *myType implements some interface while myType does not, an instance myType could contain about 1 GB of data and you want to ensure you're passing a pointer and not the value to other methods, ect. The choice of which to use depends on the use case. Although I will say, pointers are rarely worse and because that's the case I almost always use them.
When you need a pointer object use new or composite literal else use var.
Use var whenever possible as this is more likely to be allocated in stack and memory get freed as soon as scope ends. I case of new memory gets allocated most likely in heap and need to be garbage collected.
So i know in go you can initialize a struct two different ways in GO. One of them is using the new keyword which returns a pointer to the struct in memory. Or you can use the { } to make a struct. My question is when is appropriate to use each?
Thanks
I prefer {} when the full value of the type is known and new() when the value is going to be populated incrementally.
In the former case, adding a new parameter may involve adding a new field initializer. In the latter it should probably be added to whatever code is composing the value.
Note that the &T{} syntax is only allowed when T is a struct, array, slice or map type.
Going off of what #Volker said, it's generally preferable to use &A{} for pointers (and this doesn't necessarily have to be zero values: if I have a struct with a single integer in it, I could do &A{1} to initialize the field). Besides being a stylistic concern, the big reason that people normally prefer this syntax is that, unlike new, it doesn't always actually allocate memory in the heap. If the go compiler can be sure that the pointer will never be used outside of the function, it will simply allocate the struct as a local variable, which is much more efficient than calling new.
Most people use A{} to create a zero value of type A, &A{} to create a pointer to a zero value of type A. Using newis only necessary for int and that like as int{} is a no go.