golang custom struct undefined, can't import correctly - go

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

Related

Subfolder call folder Golang

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())
}

How to pass a struct as a parameter to an imported function in Go?

I have defined and created an instance of a struct in my main.go file. And I want to call a function from the functions/functions.go file using an instance of my struct as the parameter
package main
import (
"./functions"
)
type person struct {
name string
age int
}
func main() {
person1 := person{"James", 24}
functions.Hello(person1)
}
main.go
package functions
import "fmt"
type person struct {
name string
age int
}
func Hello(p person) {
fmt.Println(p.name, "is", p.age, "years old")
}
functions/functions.go
When I run this code with: go run main.go, I get the error: main.go:16:17: cannot use person1 (type person) as type functions.person in argument to functions.Hello
My question
What is the correct way to pass an instance of a struct as parameter to an imported function in Go?
The issue is that you have 2 separate person definition. Instead of redeclaring it in main, use the one in package function.
package functions
import "fmt"
type Person struct {
Name string
Age int
}
func Hello(p Person) {
fmt.Println(p.name, "is", p.age, "years old")
}
Changed to capital letter for Person and it's fields to make them export.
package main
import (
"./functions"
)
func main() {
person1 := functions.Person{"James", 24}
functions.Hello(person1)
}
You're defining two different struct types (that have the same fields, but are different) - one of them is person and the other one is called functions.person.
The correct way, in this case, would be defining your struct in functions/functions.go like this:
package functions
import "fmt"
// Use uppercase names to export struct and fields (export == public)
type Person struct {
Name string
Age int
}
func Hello(p Person) {
fmt.Println(p.Name, "is", p.Age, "years old")
}
Now in main.go, you can import the package functions and access its exported/public structs:
package main
import (
"./functions"
)
// No need to redeclare the struct, it's already defined in the imported package
func main() {
// create an object of struct Person from the functions package. Since its fields are public, we can set them here
person1 := functions.Person{"James", 24}
// call the Hello method from the functions package with an object of type functions.Person
functions.Hello(person1)
}
The key takeaway is that structs defined with the same name are not automatically the same, even if they seem similar - they are defined differently after all.
You can also do type conversions if two structs have the same fields, but that's a different story.

How to create methods for string type in Golang

I'm planning to create some method extension for the string type.
I need to write all my extension methods into a separate package.
here is my hierarchy.
root
| main.go
| validation
| validate.go
on the main.go I would like to have, "abcd".Required()
main.go
package main
import (
"fmt"
"./validation"
)
func main() {
fmt.Println( "abcd".Required() )
}
validate.go
package validation
func (s string) Required() bool {
if s != "" {
return true
}
return false
}
When I run it, will get an error.
error
cannot define new methods on non-local type string
I found some answers in other questions on StackOverflow but they don't exactly talk about the string type & having the method in a different package file.
In your validate.go create a new type String:
package validation
type String string
func (s String) Required() bool {
return s != ""
}
And then work with validation.String objects in your main:
package main
import (
"fmt"
"./validation"
)
func main() {
fmt.Println(validation.String("abcd").Required())
}
An executable example with it all in the same file here:
https://play.golang.org/p/z_LcTZ6Qvfn

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

Call a package's function without using its package name?

Example:
package "main"
import "fmt"
func main() {
fmt.Println("hey there")
}
Could be written:
package "main"
import blah "fmt"
func main() {
blah.Println("hey there")
}
But is there anyway to import fmt to achieve:
package "main"
import "fmt" // ???
func main() {
Println("hey there")
}
In C# by contrast, you can do this by using a static import (e.g., using static System.Console). Is this possible in Go?
Use the . (explicit period) import. The specification says:
If an explicit period (.) appears instead of a name, all the package's exported identifiers declared in that package's package block will be declared in the importing source file's file block and must be accessed without a qualifier.
Example:
package main
import (
. "fmt"
)
func main() {
Println("Hello, playground")
}
The use of the explicit period is discouraged in the Go community. The dot import makes programs more difficult to read because it's unclear if a name is a package-level identifier in the current package or in an imported package.
Another option is to declare a package-level variable with a reference to the function. Use a type alias to reference types.
package main
import (
"fmt"
)
var Println = fmt.Println
type ScanState = fmt.ScanState // type alias
func main() {
Println("Hello, playground")
}

Resources