my project name is family. I want to use struct which defined in father.go, use it in son.go. What I have to do?
go.mod:
module family
father\father.go:
package father
type Dad struct { Age int }
father\son\son.go:
package main
import (
"family/father"
"fmt"
)
func main() {
d := father.Dad{40}
fmt.Println(d)
}
father/father.go
package father
type Father struct {
Name string `json:"name"`
Job string `json:"job"`
}
2.father/son/son.go
package son
import (
"fmt"
"github.com/yaocanwei/demo/father"
)
type Son struct {
father.Father
Hobby string `json:"hobby"`
}
func (son *Son) EchoJob() string {
return fmt.Sprintf("%s", son.Father.Job)
}
3.main.go
package main
import (
"fmt"
"github.com/yaocanwei/demo/father/son"
)
func main() {
s := &son.Son{}
s.Job = "senior engineer"
fmt.Println(s.EchoJob())
}
Related
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:}}
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)
}
Is this valid composition? Or there are other solutions?
package main
import (
"fmt"
"strings"
)
type Person struct{ name string }
type Swimmer struct{}
func (s *Swimmer) Swim(name string) {
fmt.Println(strings.Join([]string{
name,
" is swimming",
}, ""))
}
type IronMan struct {
person Person
swimmer Swimmer
}
func (i *IronMan) Swim() {
i.swimmer.Swim(i.person.name)
}
func main() {
ironMan := IronMan{
person: Person{"Mariottide"},
swimmer: Swimmer{},
}
ironMan.Swim()
}
Go has struct embedding:
package main
import (
"fmt"
)
type Person struct{ name string }
func (p *Person) Talk(message string) {
fmt.Printf("%s says: %s\n", p.name, message)
}
type Swimmer struct {
Person
}
func (s *Swimmer) Swim() {
fmt.Printf("%s is swimming\n", s.name)
}
type IronMan struct {
Swimmer
}
func main() {
ironMan := IronMan{Swimmer{Person{"Mariottide"}}}
ironMan.Swim()
ironMan.Talk("Hey")
}
I've got 2 sibling files: main and test_two. In each is the file main.go and test_two.go respectively. In one I've got a custom struct and in the other I want to run a function with that struct as a param. I'm getting the error "undefined: Struct".
package main
import "github.com/user/test_two"
type Struct struct {
Fn string
Ln string
Email string
}
func main() {
foo := new(Struct)
foo.Fn = "foo"
foo.Ln = "bar"
foo.Email = "foo#bar.com"
test_two.Fn(foo)
test_two.go:
package test_two
import (
"fmt"
)
func Fn(arg *Struct) {
fmt.Println(arg.Fn)
}
Some rules to live by:
Don't define types in main (usually)
Don't try to import main in other packages
Don't try to import both ways (import cycle)
Always import from a lower level into a higher one (so mypkg into main)
All folders are packages, put related data/functions in them and name them well
You probably want something like this:
app/main.go
app/mypkg/mypkg.go
with contents for main.go:
// Package main is your app entry point in main.go
package main
import (
"stackoverflow/packages/mypkg"
)
func main() {
foo := mypkg.Struct{
Fn: "foo",
Ln: "foo",
Email: "foo#bar.com",
}
mypkg.Fn(foo)
}
Contents for mypkg.go:
package mypkg
import (
"fmt"
)
type Struct struct {
Fn string
Ln string
Email string
}
func Fn(s Struct) {
fmt.Printf("func called with %v\n", s)
}
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)
}