How to make a slice to be able to convert *uint64 to *int64 - go

I'm a beginner in using golang, I'm still confused about creating a slice for the child model, after that I want to take index "0" and convert it from *uint64 to *int64. Maybe i'm wrong way to convert the field, but i think i need to make the child model into a slice first before converting it. Here is the code :
params := category.PostAPICategoryParams{
Data: category.PostAPICategoryBody{
CategoryData: categoryTestData.CategoryData,
Childs: categoryTestData.Childs,
},
}
result, _ := mainSuite.h.CreateCategory(mainSuite.rt, &params.Data.CategoryData, params.Data.Childs)
categoriesParamsTest := &category.GetAPICategoryParams{
ParentID: // here is the code I need to write,
}
Here is the error when I try to write the code before creating the slice :

You have a pointer to a uint64, and want a pointer to a int64. There's no direct (safe) way to do this -- pointers to unsigned ints aren't compatible with pointers to signed ints -- but you can convert the pointed-at value to the right type (assuming the pointer isn't nil).
For example:
func convertUnsignedToSignedPointer64(p *uint64) *int64 {
if p == nil { return nil }
x := int64(*p)
return &x
}
You can also do it via the unsafe package, although I prefer avoiding the unsafe package in code I write when possible:
func convertUnsignedToSignedPointer64(p *uint64) *int64 {
return (*int64)(unsafe.Pointer(p))
}
This is ok via the rules given in unsafe.Pointer:
(1) Conversion of a *T1 to Pointer to *T2.
Provided that T2 is no larger than T1 and that the two share an
equivalent memory layout, this conversion allows reinterpreting data
of one type as data of another type.

Related

Unmarshalling in-place into a slice type in Go

Often when using go, not sure why, I get the urge to write something like
type data []event
especially when I know I'm going to be passing the slice around without thinking too much about its contents for much of the program. Sooner or later it's going to be time to unpack some data into that slice of events and I end up writing something like:
func (d *data)Unmarshal(b []byte){
//... lots of sad code that never works
}
No matter what I do I can never quite figure out how to bless my slice type with an unmarshal method that turns some bytes into the data type in-place.
When I give up, I either write a simpler function like func UnmarshalData(b []byte) data which feels like a retreat and makes it hard to write interfaces, or change the type in the first place and make a struct like
type data struct {
actuallyTheData []event
}
which feels like boilerplate purely to compensate for my lack of understanding.
So my question is: is it possible to write a function with a pointer receiver where the receiver is a slice type and that allows me to e.g. Unmarshal in-place?
The closest I can get, though it still doesn't work (and, let's face it, is pretty ugly), is something like:
type foo []int
func (f *foo) Unmarshal(s string) {
numbers := strings.Split(s, ",")
integers := make([]int, len(numbers))
for i, n := range numbers {
integer, err := strconv.Atoi(n)
if err != nil {
log.Fatal(err)
}
integers[i] = integer
}
my_f := foo(integers)
f = &my_f
}
Here's the full example: https://go.dev/play/p/3q7qehoW9tm. Why doesn't it work? What am I misunderstanding?
The last line in your Unmarshal function is overwriting the receiver itself, i.e. its address:
f = &my_f // changing the value of the pointer
The updated value won't be propagated to callers. From Declarations and Scope:
The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
You must mutate the value that is being pointed to, then callers will see it upon dereference. (As a matter of fact, you don't have to convert to the defined slice type)
func (f *foo) Unmarshal(s string) {
// ...
integers := make([]int, len(numbers))
*f = integers
}
Fixed playground: https://go.dev/play/p/3JayxQMClt-

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?

how do i create a general function to receive a map in go lang?

how can i pass map data in to a general function (isExist) to check, the given value is exist or not
passing map type may be map[int]int or map[string]string or any
func IsExist(text int, data map[interface{}]interface{}) bool {
for key, _ := range data {
if data[key] == text {
return true
}
}
return false
}
func main() {
var data = make(map[string]int)
//var data =map[interface {}]interface{} this case will working fine
data["a"] = 1
data["b"] = 2
fmt.Println(IsExist(2, data))
//throwing error that 'cannot use data (type map[string]int) as type map[interface {}]interface {} in argument to IsExist'
}
please let me know how can you generalize it?
Go's type system can't do that. map[string]int and map[interface {}]interface{} are distinct types. Besides, storage/representation of objects in memory depends on the type. A string has one memory layout. But the very same string, packaged as a interface{} - totally different. For the same reasons you can't "cast" a []int to a []interface{}. You have to copy the elements into the new slice.
Same here. Either make your map a map[interface {}]interface{} from the start, or copy all key-values pairs to one, prior to the call of the generic function.

Check if struct field is empty

I would like to iterate over the fields of a struct after unmarshalling a JSON object into it and check for the fields whose value was not set (i.e. are empty).
I can get the value of each field and compare that to the reflect.Zero value for the corresponding type
json.Unmarshal([]byte(str), &res)
s := reflect.ValueOf(&res).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
v := reflect.ValueOf(f.Interface())
if (reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())) {
....
But the problem, of course, is that this will not work well for bool or int values.
If a bool field is set to false in the JSON or an int field is set to 0, they will be equal to the zero value of their type. The aforementioned check will consider the fields to be uninitialized, even though they actually have a value set.
I know one way around this is to use pointers, but I just don't see how that would be possible in this case as I'm working with reflect.Value types, not the actual struct.
As you've mentioned, you could use pointers.
The json package can handle unmarshalling values into pointers for you. You've not included the json payload you are trying to unmarshal, or the struct you are unmarshalling into, so I've made up an example.
// json
{
"foo": true,
"number_of_foos": 14
}
// go struct
type Foo struct {
Present bool `json:"foo"`
Num int `json:"number_of_foos"`
}
Here if the keys foo or number_of_foos is missing, then as you've correctly observed, the zero value (false/ 0) will be used. In general the best advice is to make use of the zero value. Create structures so that zero values of false are useful, rather than a pain.
This is not always possible, so changing the types of the fields in the Foo struct to be pointers will allow you to check the 3 cases you are after.
Present
Present and zero
Missing
here is the same struct with pointers:
// go struct
type Foo struct {
Present *bool `json:"foo"`
Num *int `json:"number_of_foos"`
}
Now you can check for presence of the value with fooStruct.Present != nil and if that condition holds, you can assume that the value in the field is the one you wanted.
There is no need to use the reflect package.
Another way of doing the same is by implementing json.Unmarshaler.
type MaybeInt struct {
Present bool
Value int
}
func (i *MaybeInt) UnmarshalJSON(bs []byte) error {
if e := json.Unmarshal(bs, &i.Value); e != nil {
return e
}
i.Present = true
return nil
}
You can then use MaybeInt in your top-level structure:
type Top struct {
N MaybeInt `json:"n"`
M MaybeInt `json:"m"`
}
func main() {
t := Top{}
if e := json.Unmarshal([]byte(` { "n": 4930 } `), &t); e != nil {
panic(e)
}
fmt.Println(t.N, t.M)
}
See it working on the playground
Try using the golang validator package. The validator package offers a required attribute that might do the required job for your need. The official documentation for required attribute states:
This validates that the value is not the data types default zero value. For numbers ensures value is not zero. For strings ensures value is not "". For slices, maps, pointers, interfaces, channels and functions ensures the value is not nil.
The example illustrating the same can be seen at: https://github.com/go-playground/validator/blob/v9/_examples/struct-level/main.go.
Hope this solves your requirement.

dereferencing string literal in Go [duplicate]

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"}

Resources