dereferencing string literal in Go [duplicate] - go

I have a struct type with a *int64 field.
type SomeType struct {
SomeField *int64
}
At some point in my code, I want to declare a literal of this (say, when I know said value should be 0, or pointing to a 0, you know what I mean)
instance := SomeType{
SomeField: &0,
}
...except this doesn't work
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
So I try this
instance := SomeType{
SomeField: &int64(0),
}
...but this also doesn't work
./main.go:xx: cannot take the address of int64(0)
How do I do this? The only solution I can come up with is using a placeholder variable
var placeholder int64
placeholder = 0
instance := SomeType{
SomeField: &placeholder,
}
Note: the &0 syntax works fine when it's a *int instead of an *int64. Edit: no it does not. Sorry about this.
Edit:
Aparently there was too much ambiguity to my question. I'm looking for a way to literally state a *int64. This could be used inside a constructor, or to state literal struct values, or even as arguments to other functions. But helper functions or using a different type are not solutions I'm looking for.

The Go Language Specification (Address operators) does not allow to take the address of a numeric constant (not of an untyped nor of a typed constant).
The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.
For reasoning why this isn't allowed, see related question: Find address of constant in go. A similar question (similarly not allowed to take its address): How can I store reference to the result of an operation in Go?
0) Generic solution (from Go 1.18)
Generics are added in Go 1.18. This means we can create a single, generic Ptr() function that returns a pointer to whatever value we pass to it. Hopefully it'll get added to the standard library. Until then, you can use github.com/icza/gog, the gog.Ptr() function (disclosure: I'm the author).
This is how it can look like:
func Ptr[T any](v T) *T {
return &v
}
Testing it:
i := Ptr(2)
log.Printf("%T %v", i, *i)
s := Ptr("abc")
log.Printf("%T %v", s, *s)
x := Ptr[any](nil)
log.Printf("%T %v", x, *x)
Which will output (try it on the Go Playground):
2009/11/10 23:00:00 *int 2
2009/11/10 23:00:00 *string abc
2009/11/10 23:00:00 *interface {} <nil>
Your other options (prior to Go 1.18) (try all on the Go Playground):
1) With new()
You can simply use the builtin new() function to allocate a new zero-valued int64 and get its address:
instance := SomeType{
SomeField: new(int64),
}
But note that this can only be used to allocate and obtain a pointer to the zero value of any type.
2) With helper variable
Simplest and recommended for non-zero elements is to use a helper variable whose address can be taken:
helper := int64(2)
instance2 := SomeType{
SomeField: &helper,
}
3) With helper function
Note: Helper functions to acquire a pointer to a non-zero value are available in my github.com/icza/gox library, in the gox package, so you don't have to add these to all your projects where you need it.
Or if you need this many times, you can create a helper function which allocates and returns an *int64:
func create(x int64) *int64 {
return &x
}
And using it:
instance3 := SomeType{
SomeField: create(3),
}
Note that we actually didn't allocate anything, the Go compiler did that when we returned the address of the function argument. The Go compiler performs escape analysis, and allocates local variables on the heap (instead of the stack) if they may escape the function. For details, see Is returning a slice of a local array in a Go function safe?
4) With a one-liner anonymous function
instance4 := SomeType{
SomeField: func() *int64 { i := int64(4); return &i }(),
}
Or as a (shorter) alternative:
instance4 := SomeType{
SomeField: func(i int64) *int64 { return &i }(4),
}
5) With slice literal, indexing and taking address
If you would want *SomeField to be other than 0, then you need something addressable.
You can still do that, but that's ugly:
instance5 := SomeType{
SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5
What happens here is an []int64 slice is created with a literal, having one element (5). And it is indexed (0th element) and the address of the 0th element is taken. In the background an array of [1]int64 will also be allocated and used as the backing array for the slice. So there is a lot of boilerplate here.
6) With a helper struct literal
Let's examine the exception to the addressability requirements:
As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.
This means that taking the address of a composite literal, e.g. a struct literal is ok. If we do so, we will have the struct value allocated and a pointer obtained to it. But if so, another requirement will become available to us: "field selector of an addressable struct operand". So if the struct literal contains a field of type int64, we can also take the address of that field!
Let's see this option in action. We will use this wrapper struct type:
type intwrapper struct {
x int64
}
And now we can do:
instance6 := SomeType{
SomeField: &(&intwrapper{6}).x,
}
Note that this
&(&intwrapper{6}).x
means the following:
& ( (&intwrapper{6}).x )
But we can omit the "outer" parenthesis as the address operator & is applied to the result of the selector expression.
Also note that in the background the following will happen (this is also a valid syntax):
&(*(&intwrapper{6})).x
7) With helper anonymous struct literal
The principle is the same as with case #6, but we can also use an anonymous struct literal, so no helper/wrapper struct type definition needed:
instance7 := SomeType{
SomeField: &(&struct{ x int64 }{7}).x,
}

Use a function which return an address of an int64 variable to solve the problem.
In the below code we use function f which accepts an integer and
returns a pointer value which holds the address of the integer. By using this method we can easily solve the above problem.
type myStr struct {
url *int64
}
func main() {
f := func(s int64) *int64 {
return &s
}
myStr{
url: f(12345),
}
}

There is another elegant way to achieve this which doesn't produce much boilerplate code and doesn't look ugly in my opinion. In case I need a struct with pointers to primitives instead of values, to make sure that zero-valued struct members aren't used across the project, I will create a function with those primitives as arguments.
You can define a function which creates your struct and then pass primitives to this function and then use pointers to function arguments.
type Config struct {
Code *uint8
Name *string
}
func NewConfig(code uint8, name string) *Config {
return &Config{
Code: &code,
Name: &name,
}
}
func UseConfig() {
config := NewConfig(1, "test")
// ...
}
// in case there are many values, modern IDE will highlight argument names for you, so you don't have to remember
func UseConfig2() {
config := NewConfig(
1,
"test",
)
// ...
}

If you don't mind using third party libraries, there's the lo package which uses generics (go 1.18+) which has the .ToPtr() function
ptr := lo.ToPtr("hello world")
// *string{"hello world"}

Related

get reflect.struct from interface

hi a have this func for get type of value, but i try this and never can get reflect.struct:
type Test struct {
Code int
Name string
}
func main(){
test := getTest()
data, err := getBytes(slice...)
sanitizedFile := bytes.Split(data, []byte("\r\n"))
err = Unmarshal(sanitizedFile[0], &test)
}
func getTest() interface{} {
return Test{}
}
With this code i don't can get the reflecet.struct from v params in Unmarshall func
func Unmarshal(data []byte, v interface{}) error {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Ptr {
rvElem := rv.Elem()
switch rvElem.Kind() {
case reflect.Struct:
// implement me
}
}
return ErrInvalid
}
I would like to know if I can somehow find out if an interface is of type struct or access the values ​​of that struct.
I think the real problem here is illustrated by this quote:
I would like to know if I can somehow find out if an interface is of type struct or access the values ​​of that struct.
An interface value isn't "of type struct". Never! An interface value can contain a value whose type is some structure, but it is not a value of that type. It just contains one. This is similar to the way that a box1 you get from Amazon can contain a corkscrew, but the box is not a corkscrew, ever.
Given a non-nil value of type interface I for some interface type I, you know that you have a value that implements the methods of I. Since {} is the empty set of methods, all types implement it, so given a (still non-nil) value of type interface{}, you have a value that implements no methods. That's not at all useful by itself: it means you can invoke no methods, which means you can't do anything method-like.
But just because you can't do anything method-y doesn't mean you can't do anything at all. Any interface value, regardless of the interface type, can have a type-assertion used on it:
iv := somethingThatReturnsAnInterface()
cv := iv.(struct S) // assert that iv contains a `struct S`
If iv does in fact contain a struct S value—if that's what's inside the box once you open it—then this type-assertion doesn't panic, and cv winds up with the concrete value of type struct S. If panic is undesirable, we can use the cv, ok := iv.(struct S) form, or a type switch. All of these—including the version that panics—work by checking the type of the value inside the interface.
What this—or, more precisely, the way the Go language is defined—tells us is that the interface "box" really holds two things:
a concrete type, and
a concrete value.
Well, that is, unless it holds a <nil, nil> pair, in which case iv == nil is true. Note that the iv == nil test actually tests both parts.
If Go had a syntax for this, we could write something like iv.type and iv.value to get at the two separate parts. But we can't do that. We have to use type assertions, type-switch, or reflect. So, going back to this:
I would like to know if I can somehow find out if an interface is of type struct
we can see that the question itself is just a little malformed. We don't want to know if an interface value has this type. We want to know if a non-nil interface's held value is of this type, as if we could inspect iv.type and iv.value directly.
If you have a limited set of possible types, you can use the type-switch construct, and enumerate all your allowed possiblities:
switch cv := iv.(type) {
case struct S:
// work with cv, which is a struct S
case *struct S:
// work with cv, which is a *struct S
// add more cases as appropriate
}
If you need more generality, instead of doing the above, we end up using the reflect package:
tv := reflect.TypeOf(iv)
or:
vv := reflect.ValueOf(iv)
The latter is actually the more useful form, since vv captures both the iv.type pseudo-field and the iv.value pseudo-field.
As mkopriva notes in a comment, test, in your sample code, has type interface{}, so &test has type *interface{}. In most cases this is not a good idea: you just want to pass the interface{} value directly.
To allow the called function to set the object to a new value, you will want to pass a pointer to the object as the interface value. You do not want to pass a pointer to the interface while having the interface hold the struct "in the box" as it were. You need a reflect.Value on which you can invoke Set(), and to get one, you will need to follow an elem on the reflect.Value that is a pointer to the struct (not one that is a pointer to the interface).
There's a more complete example here on the Go Playground.
1This is partly an allusion to "boxed values" in certain other programming languages (see What is boxing and unboxing and what are the trade offs?), but partly literal. Don't mistake Go's interfaces for Java's boxed values, though: they are not the same at all.
Maybe what you need is type assertion?
t, ok := v.(myStruct)
https://tour.golang.org/methods/15
In any case this code prints "struct":
type tt struct {}
var x tt
var z interface{}
z = x
v := reflect.ValueOf(z).Kind()
fmt.Printf("%v\n", v)
And see this for setting the value of a struct field using reflection:
Using reflect, how do you set the value of a struct field?

go when to use & or not?

I am confused whether to use a & with go when declaring a variable and init with a struct
say we have a struct wrapper
type HttpResult struct {
Status int32 `json:"status"`
Msg string `json:"msg"`
Data interface{} `json:"data,omitempty"`
}
and a struct defining the user model
type OmUser struct {
Id primitive.ObjectID `json:"id" bson:"_id,omitempty"`
Name string `json:"name"`
Password string `json:"password"`
Email string `json:"email"`
}
And the following declaring seems give the same result:
myOmUser := OmUser{ //note no & sign here
Name: "Tony",
Password: "mypass",
Email: "tony#foo.com"
}
httpResult := &HttpResult{
Status: 0,
Msg: "ok",
Data: myOmUser,
}
js, _ := json.Marshal(httpResult)
fmt.Println(js)
Or
myOmUser := &OmUser{ //note the & sign
Name: "Tony",
Password: "mypass",
Email: "tony#foo.com"
}
httpResult := &HttpResult{
Status: 0,
Msg: "ok",
Data: myOmUser,
}
js, _ := json.Marshal(httpResult)
fmt.Println(js)
so, when to use & and why?
In your particular example it doesn't make a difference.
But when we look at an example of using json.Unmarshal() it makes a bit more sense:
jsonBlob := []byte(`{"id": "1", "name": "bob", "password": "pass", "email", "hi#me.com"}`)
var newOmUser OmUser
err := json.Unmarshal(jsonBlob, &newOmUser)
if err != nil {
panic(err)
}
Here we declare the variable before hand, and then we use the & to pass a pointer to that variable into the Unmarshal function.
That means that the Unmarshal function can reach out and update that variable, even though it's declared outside of the function.
Without the &, the Unmarshal function would get a copy of the newOmUser variable, and it would leave the original newOmUser variable that we declared empty.
When it comes to pointers, my general rule of thumb is:
Don't use them unless you have to.
If you need to use any unmarshalling functions, you'll need them. There are lots of other functions that make use of them.
Here's a quick exercise that helps me understand a little more about pointers:
func uppercase(s string) {
s = strings.ToUpper(s)
fmt.Println(s)
}
// Same as the uppercase() function, but works with a pointer.
func uppercasePointer(s *string) {
*s = strings.ToUpper(*s)
fmt.Println(*s)
}
name := "bob"
uppercase(name) // prints 'BOB'
fmt.Println(name) // prints 'bob' - our variable was not changed
name2 := "bobpointer"
uppercasePointer(&name2) // prints 'BOBPOINTER'
fmt.Println(name2) // prints 'BOBPOINTER' - our variable was changed
When we call the uppercase(name) function, go makes a copy of the name variable and sends it to the uppercase function.
Whatever the function does to that copy that it received stays in the function. The original variable that we declared outside the function is not changed.
When we call the uppercasePointer(&name2) function, we are sending a pointer to the name2 variable we declared.
The function can use that pointer to reach out and update the name2 variable that we declared earlier.
At first, you might not see the point of pointers, but as you continue to use go, you will see that they help us solve some complex problems.
Empty interface type in Go can hold values of any type. Tour here.
So in your HttpResult.Data is an empty interface type. So you can assigne any type to it.
The difference between defining a variable with & is getting a pointer of that type. Tour here.
Those are obviously two types with two different functionalities in Go. But you can assign both to empty interface type variable because its accepting values of any type.
package main
import (
"fmt"
"reflect"
)
type OmUser struct {
}
func main() {
myOmUser := OmUser{}
myOmUser2 := &OmUser{}
fmt.Println(reflect.TypeOf(myOmUser)) //main.OmUser
fmt.Println(reflect.TypeOf(myOmUser2)) //*main.OmUser
}
For more details about &, read Go doc address operators
For an
operand x of type T, the address operation &x generates a pointer of
type *T to x. The operand must be addressable, that is, either a
variable, pointer indirection, or slice indexing operation; or a field
selector of an addressable struct operand; or an array indexing
operation of an addressable array. As an exception to the
addressability requirement, x may also be a (possibly parenthesized)
composite literal. If the evaluation of x would cause a run-time
panic, then the evaluation of &x does too.
fooA := &Foo{}
fooA has type *Foo.
fooB := Foo{}
fooB has type Foo.
https://tour.golang.org/moretypes/1
In practice, this means if you had a func that accepted type *Foo you could do either of the following...
func someFunc(f *Foo) {
// ...
}
fooA := &Foo{}
someFunc(fooA)
fooB := Foo{}
someFunc(&fooB)
So realistically, create whichever you need to be honest.

Generic function which appends two arrays

Not able to figure out how to convert interface{} returned from function into an array of structs
As part of some practise i was trying to create a function which can take 2 slices of some type and concatenates both and returns the slice.
The code can be found here - https://play.golang.org/p/P9pfrf_qTS1
type mystruct struct {
name string
value string
}
func appendarr(array1 interface{}, array2 interface{}) interface{} {
p := reflect.ValueOf(array1)
q := reflect.ValueOf(array2)
r := reflect.AppendSlice(p, q)
return reflect.ValueOf(r).Interface()
}
func main() {
fmt.Println("=======")
array1 := []mystruct{
mystruct{"a1n1", "a1v1"},
mystruct{"a1n2", "a1v2"},
}
array2 := []mystruct{
mystruct{"a2n1", "a2v1"},
mystruct{"a2n2", "a2v2"},
}
arrayOp := appendarr(array1, array2)
fmt.Printf("arr: %#v\n", arrayOp) // this shows all the elements from array1 and 2
val := reflect.ValueOf(arrayOp)
fmt.Println(val) // output is <[]main.mystruct Value>
fmt.Println(val.Interface().([]mystruct)) // exception - interface {} is reflect.Value, not []main.mystruct
}
I may have slices of different types of structs. I want to concatenate them and access the elements individually.
If there is any other way of achieving the same, please do let me know.
reflect.Append() returns a value of type reflect.Value, so you don't have to (you shouldn't) pass that to reflect.ValueOf().
So simply change the return statement to:
return r.Interface()
With this it works and outputs (try it on the Go Playground):
=======
arr: []main.mystruct{main.mystruct{name:"a1n1", value:"a1v1"}, main.mystruct{name:"a1n2", value:"a1v2"}, main.mystruct{name:"a2n1", value:"a2v1"}, main.mystruct{name:"a2n2", value:"a2v2"}}
[{a1n1 a1v1} {a1n2 a1v2} {a2n1 a2v1} {a2n2 a2v2}]
[{a1n1 a1v1} {a1n2 a1v2} {a2n1 a2v1} {a2n2 a2v2}]
You also don't need to do any reflection-kungfu on the result: it's your slice wrapped in interface{}. Wrapping it in reflect.Value and calling Value.Interface() on it is just a redundant cycle. You may simply do:
arrayOp.([]mystruct)
On a side note: you shouldn't create a "generic" append() function that uses reflection under the hood, as this functionality is available as a built-in function append(). The builtin function is generic, it gets help from the compiler so it provides the generic nature at compile-time. Whatever you come up with using reflection will be slower.

What is the difference between reflect.ValueOf() and Value.Elem() in go?

I started learning golang a couple of days ago and found reflect.Valueof() and Value.Elem() quite confusing. What is the difference between this two function/methods and how to use them correctly?
Both function/methods return a Value, and according to the go doc
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
I found this code from a post on stackoverflow but still don't understand when to use .Elem()
func SetField(obj interface{}, name string, value interface{}) error {
// won't work if I remove .Elem()
structValue := reflect.ValueOf(obj).Elem()
structFieldValue := structValue.FieldByName(name)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set %s field value", name)
}
structFieldType := structFieldValue.Type()
// won't work either if I add .Elem() to the end
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value %v type %v didn't match obj field type %v",val,val.Type(),structFieldType)
}
structFieldValue.Set(val)
return nil
}
reflect.ValueOf() is a function, think of it as the entry point to reflection. When you have a "non-reflection" value, such as a string or int, you can use reflect.ValueOf() to get a reflect.Value descriptor of it.
Value.Elem() is a method of reflect.Value. So you can only use this if you already have a reflect.Value. You may use Value.Elem() to get the value (reflect.Value) pointed by the value wrapped by the original reflect.Value. Note that you may also use reflect.Indirect() for this. There's another "use case" for Value.Elem(), but it's more "advanced", we return to it at the end of the answer.
To "leave" reflection, you may use the general Value.Interface() method, which returns you the wrapped value as an interface{}.
For example:
var i int = 3
var p *int = &i
fmt.Println(p, i)
v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer
v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i's value: 3
This will output (try it on the Go Playground):
0x414020 3
0x414020
3
For a great introduction to Go's reflection, read The Go Blog: The Laws of Reflection. Although if you're just starting with Go, I'd focus on other things and leave reflection for a later adventure.
Another use case for Value.Elem()
This is kind of an advanced topic, so don't freak out if you don't understand it. You don't need to.
We saw how Value.Elem() can be used to "navigate" when a pointer is wrapped in the reflect.Value. Doc of Value.Elem() says:
Elem returns the value that the interface v contains or that the pointer v points to.
So if reflect.Value wraps an interface value, Value.Elem() may also be used to get the concrete value wrapped in that interface value.
Interfaces in Go is its own topic, for the internals, you may read Go Data Structures: Interfaces by Russ Cox. Again, not necessarily a topic for Go starters.
Basically whatever value you pass to reflect.ValueOf(), if it's not already an interface value, it will be wrapped in an interface{} implicitly. If the passed value is already an interface value, then the concrete value stored in it will be passed as a interface{}. This second "use case" surfaces if you pass a pointer to interface (which is otherwise very rare in Go!).
So if you pass a pointer to interface, this pointer will be wrapped in an interface{} value. You may use Value.Elem() to get the pointed value, which will be an interface value (not a concrete value), and using Value.Elem() again on this will give you the concrete value.
This example illustrates it:
var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader
v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type()) // *os.File
v2 := reflect.ValueOf(&r) // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type()) // *io.Reader
fmt.Println(v2.Elem().Type()) // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File
Try it on the Go Playground.

What's happening with these pointers?

I wrote some odd code, but I'm not sure why it works and what I can learn from it. I have a slice type build from another struct. I made a function on the slice type to modify itself. To do this, I seem to have to throw around *'s a little much.
I'm trying to learn about pointers in Go and would like a little help. Here's an example (http://play.golang.org/p/roU3MEeT3q):
var ClientNames = []string {"Client A", "Client B", "ClientC"}
type InvoiceSummaries []InvoiceSummary
type InvoiceSummary struct {
Client string
Amt int
}
func (summaries *InvoiceSummaries) BuildFromAbove() {
for _, name := range ClientNames {
*summaries = append(*summaries, InvoiceSummary{name, 100})
}
}
My question is: What is the purpose for each of these * and why am I not using any &?
What is the purpose for each of these * ?
By making the method receiver as pointer, you could easily change the property of the object. I think that's one of the benefit. This example below will prove it.
package main
import "fmt"
type someStruct struct {
someVar int
}
func (s someStruct) changeVal1(newVal int) {
s.someVar = newVal
}
func (s *someStruct) changeVal2(newVal int) {
s.someVar = newVal
}
func main() {
s := someStruct{0}
fmt.Println(s) // {0}
s.changeVal1(3)
fmt.Println(s) // {0}
s.changeVal2(4)
fmt.Println(s) // {4}
(&s).changeVal2(5)
fmt.Println(s) // {5}
}
and why am I not using any &?
Pointer method receiver is quite special, it can also be called from non-pointer struct object. Both of s.changeVal2(4) and (&s).changeVal2(5) are valid & will affect the value of someVar.
Example http://play.golang.org/p/sxCnCD2D6d
You have to use a pointer for the receiver - (summaries *InvoiceSummaries) - because otherwise the argument is passed by value, having a pointer means you pass a reference to the value instead. If not for that, then you couldn't modify the collection at all.
Inside of the methods body you have use * because it is the dereferncing operator and returns the value at the address. Ampersand (&) is the opposite, it gives the address of a value.
Nothing wrong with your code but normally addresses to slices aren't used. A slice is a small struct that gophers are normally happy to pass by value. If a method or function is creating a new slice, the gopher is happy to return the new slice, by value again, as the return value.
Of course passing a slice by value doesn't guarantee anything about the backing store remaining unchanged when the method/function returns. So it can't be used as a way of guaranteeing the data elements of the slice haven't mutated.

Resources