Property name of a structure to string - go

I would like to know if it is possible to get the name of a property from a structure and convert it to string.
For example in the following code:
package main
import "fmt"
type StructA struct {
ValueAA string
ValueAB string
}
type StructB struct {
ValueBA string
ValueBB string
RefStructA StructA
}
func main() {
//pass any attribute of any structure
fmt.Println(castProperty(StructB.RefStructA.ValueAA))
//print the name passed but in string. Do not print the value
//expected output: "StructB.RefStructA.ValueAA"
}
func castProperty(value interface{}) string {
//some code
}
Is it possible to write a function that allows obtaining the name of the property of a structure and converted to a string? property value is not required.

That's called Reflection. I let you read the page, it lets you do what you want.
First, read the The first law of reflection: https://go.dev/blog/laws-of-reflection
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
}
https://play.golang.org/p/OuGgD1TlSMO

I am not sure exactly how do you want to give input to your function but here is an example that may help you
package main
import (
"log"
"reflect"
)
func main() {
getPropertyName(B{})
}
type A struct {
field1 string
}
type B struct {
field A
}
func getPropertyName(b interface{}) {
parentType := reflect.TypeOf(b)
val := reflect.ValueOf(b)
for i := 0; i< val.Type().NumField(); i++ {
t := val.Type().Field(i)
ty := val.Type().Field(i).Type.Name()
log.Println(parentType.Name()+"."+ t.Name+"."+ty)
}
}

you could do something like this :
package main
import (
"fmt"
)
type StructA struct {
ValueAA string
ValueAB string
}
type StructB struct {
ValueBA string
ValueBB string
RefStructA StructA
}
func main() {
x := &StructB{RefStructA: StructA{ValueAA: "something"}}
fmt.Printf("%+v", x)
}
out :
&{ValueBA: ValueBB: RefStructA:{ValueAA:something ValueAB:}}

Related

Missing type in composite literal while working with string[][] in map in golang

This is my code:
package main
import (
"fmt"
)
type person struct {
//name [][]string{};
name [][]string
}
func main() {
var people = map[string]*person{}
people["first person"] = &person{name:{{"My name","30"}}}
fmt.Println(people["first person"])
}
I have an error:
missing type in composite literal
I want output as [[My name,30]]
Could someone help me?
Here is working example. You must declare type of composed literal before using.
package main
import (
"fmt"
)
type person struct {
//name [][]string{};
name [][]string
}
func main() {
var people = map[string]*person{}
people["first person"] = &person{name: [][]string{{"John", "30"}}}
fmt.Println(people["first person"])
}
You are missing type while creating an instance pointer and initializing it, it should be:
&person{name: [][]string{{"My name, 30"}}}
Below is the working example:
package main
import (
"fmt"
)
type person struct {
name [][]string
}
func main() {
var people = map[string]*person{}
people["first person"] = &person{name: [][]string{{"My name, 30"}}}
fmt.Println(people["first person"].name)
}

Go Relflect Declare type struct

I wish I could recover my type of structure and declare a variable of that type .
I tried with Reflect but I can not find the way .
package main
import (
"fmt"
"reflect"
)
type M struct {
Name string
}
func main() {
type S struct {
*M
}
s := S{}
st := reflect.TypeOf(s)
Field, _ := st.FieldByName("M")
Type := Field.Type
test := Type.Elem()
fmt.Print(test)
}
Use reflect.New with your type, here's an example of setting Name on a new instance of M struct using reflection:
package main
import (
"fmt"
"reflect"
)
type M struct {
Name string
}
func main() {
type S struct {
*M
}
s := S{}
mStruct, _ := reflect.TypeOf(s).FieldByName("M")
mInstance := reflect.New(mStruct.Type.Elem())
nameField := mInstance.Elem().FieldByName("Name")
nameField.SetString("test")
fmt.Print(mInstance)
}

Go: embedded type's field initialization in derived type

Here is the code that works:
package main
import (
"fmt"
)
type Base struct {
Field int
}
type Derived struct {
Base
}
func main() {
d := &Derived{}
d.Field = 10
fmt.Println(d.Field)
}
And here's the code that fails to compile with ./main.go:17: unknown Derived field 'Field' in struct literal
package main
import (
"fmt"
)
type Base struct {
Field int
}
type Derived struct {
Base
}
func main() {
d := &Derived{
Field: 10,
}
fmt.Println(d.Field)
}
What exactly is going on here? Sorry if it's obvious, but I just don't understand.
From the language specification:
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
So that's why it doesn't work.
Here are two possible ways to work around that limitation, each illustrated in the following function:
func main() {
d := &Derived{
Base{Field: 10},
}
e := new(Derived)
e.Field = 20
fmt.Println(d.Field)
fmt.Println(e.Field)
}
To initialize composed objects you have to initialize the embedded field, like any other object:
package main
import (
"fmt"
)
type Base struct {
Field int
}
type Derived struct {
Base
}
func main() {
d := &Derived{
Base{10},
}
fmt.Println(d.Field)
}

Go fmt.Println display wrong contain

I am studying GO by using "a tour of go"
The code is doing very simple things, combine first and last together and output on screen.
The output is a hex address instead of "aaabbb" after I run the code. Could anyone can help me out? Thank you
package main
import "fmt"
type Name struct{
first,last string
}
func (name Name) fullName() string{
return (name.first + name.last)
}
func main(){
v := Name{"aaa","bbb"}
fmt.Println(v.fullName)
}
You are not calling the function fullName. you are just passing 'the pointer' to it:
see this http://play.golang.org/p/GjibbfoyH0
package main
import "fmt"
type Name struct {
first, last string
}
func (name Name) fullName() string {
return (name.first + name.last)
}
func main() {
v := Name{"aaa", "bbb"}
fmt.Println(v.fullName())
}
Use the result of the method
fmt.Println(v.fullName())
not the address of the method
fmt.Println(v.fullName)
For example,
package main
import "fmt"
type Name struct{
first,last string
}
func (name Name) fullName() string{
return (name.first + name.last)
}
func main(){
v := Name{"aaa","bbb"}
fmt.Println(v.fullName())
}
Output:
aaabbb

How to use pointer type in struct initializer?

I cannot figure out how to initialize structure field when it is a reference type alias of the one of the number types:
package main
import (
"fmt"
"encoding/json"
)
type Nint64 *int64
type MyStruct struct {
Value Nint64
}
func main() {
data, _ := json.Marshal(&MyStruct{ Value : ?? 10 ?? })
fmt.Println(string(data))
}
You can't, you will have to add an extra step playground:
func NewMyStruct(i int64) *MyStruct {
return &MyStruct{&i}
}
func main() {
i := int64(10)
data, _ := json.Marshal(&MyStruct{Value: Nint64(&i)})
fmt.Println(string(data))
//or this
data, _ = json.Marshal(NewMyStruct(20))
fmt.Println(string(data))
}
I don't think you want to reference to the address of an int64 ...
package main
import (
"encoding/json"
"fmt"
)
type Nint64 int64
type MyStruct struct {
Value Nint64
}
func main() {
data, _ := json.Marshal(&MyStruct{Value: Nint64(10)})
fmt.Println(string(data))
}
http://play.golang.org/p/xafMLb_c73

Resources