Two go files having package declaration main inside a package - go

So i have created a package named app inside which there are two go files named entry.go and entry1.go where entry.go is having function main while entry1.go is having a function which is being called by entry.go.
content of entry.go:
package main
import "fmt"
import "app"
func main(){
fmt.Println("app/entry.go")
app.FunctionOne()
}
content of entry1.go:
package main
func FunctionOne() {
fmt.Println("this is having different name")
}
on running go build it shows import cycle

You don't have to import app! you're in the same package which is main package.
just remove the extra import, and use FunctionOne() no need for app

Related

Package names in import statement are removed automatically in VSCODE for .go file . How to resolve this?

I start typing the code in .go file using VSCODE Editor as below
package main
import (
"fmt"
"log"
"math/rand"
"net/http"
)
func main() {
fmt.Println("Hello World!")
}
as soon as the above is typed I save the file and then I find that I have lost the statement I have typed in import and the code remains as follows
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
though I am aware that the unused imports are automatically removed, I do not know how to resolve this. I need these packages for the remaining part of my source code and only with that understanding I have included these package names even when I began to write the code.
Which setting should I use to resolve this in VSCode Editor
though I am aware that the unused imports are automatically removed, I
do not know how to resolve this.
In vscode setting.json set this config
"[go]": {
"editor.codeActionsOnSave": {
"source.organizeImports": false
}
}

How golang's init() works. I am confused

I have a init() function defined in "config/config.go"
config.go
package config
import(
log "github.com/sirupsen/logrus"
)
func init() {
log.SetReportCaller(true)
}
I have another go file called auth.go in auth package
package auth
import(
log "github.com/sirupsen/logrus"
)
func auth(username string, pwd string) {
//some auth code
log.Info("Auth success")
}
When log.Info() is called in auth.go the log prints as below
2018-11-09T16:38:27+05:30 auth/auth.go:36 level=info msg="Auth success"
What I am confused here is that, how "log" in auth.go is aware of the settings done in config.go. log.SetReportCaller() is in config.go but even when auth.go is logged it takes settings of log.SetReportCaller() done in config.go
Since log.SetReportCaller() is not set in auth.go expected log should be as below without showing line number of caller method.
2018-11-09T16:38:27+05:30 level=info msg="Auth success"
main.go
package main
import (
"path/to/auth"
log "github.com/sirupsen/logrus"
"net/http"
)
func main() {
r := server.Route()
log.Info("Listening on 8080")
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}
auth/router.go
package auth
import (
"github.com/gorilla/mux"
"github.com/rs/cors"
"net/http"
)
func Route() http.Handler {
r := mux.NewRouter()
// UI handlers
r.HandleFunc("/", IndexPageHandler)
r.HandleFunc("/login", LoginHandler).Methods("POST")
handler := cors.Default().Handler(r)
return
}
auth/login.go
package auth
import (
"fmt"
"path/to/config"
log "github.com/sirupsen/logrus"
"net/http"
)
func LoginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
status, userName, mail, _ := auth(username, password)
//some code goes here
}
Kindly explain how this is happening
Check this diagram to understand how init() work: diagram
Initialization order are as follows,
If a package imports other packages, the imported packages are initialised first.
Package level variables are initialised then.
init function of current package is called next. A package can have multiple init functions (either in a single file or distributed across multiple files) and they are called in the order in which they are presented to the compiler.
You will found an example explaining this here.
I am suspecting in dependency tree, there is a common ancestor file that import both config package and auth package.
Here is official doc on initialization: Package initialization
UPD: As you have added respective codes, let's visualize what is happening here. Look at the picture bellow,
What happening:
Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.
auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.
config package complete initialization(log.SetReportCaller(true) is called).
auth package complete initialization.
main package complete initialization.
main() function starts executing...
The behavior you're asking about actually has nothing to do with how init() functions work. SetReportCaller sets a global variable in github.com/sirupsen/logrus, not in your config or auth packages. So it doesn't matter where you call that function or where you call log.Info et al; the setting affects all calls to logrus regardless of call origin.

How to access a struct from an external package in Go

I'm trying to import a struct from another package in the following file:
// main.go
import "path/to/models/product"
product = Product{Name: "Shoes"}
// models/product.go
type Product struct{
Name string
}
But in the main.go file the struct Product is undefined. How do I import the struct?
In Go you import "complete" packages, not functions or types from packages.
(See this related question for more details: What's C++'s `using` equivalent in golang)
See Spec: Import declarations for syntax and deeper explanation of the import keyword and import declarations.
Once you import a package, you may refer to its exported identifiers with qualified identifiers which has the form: packageName.Identifier.
So your example could look like this:
import "path/to/models/product"
import "fmt"
func main() {
p := product.Product{Name: "Shoes"}
// Use product, e.g. print it:
fmt.Println(p) // This requires `import "fmt"`
}

How to persist "package" states in Go?

My goal is to encapsulate in one module/package.
Main package:
package main
import (
"github.com/zenazn/goji"
"./routes"
)
func main(){
routes.Setup()
goji.Serve()
}
And another package:
package routes
import "github.com/zenazn/goji"
func Setup() {
goji.Get("/static", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "static!")
})
}
How can I do this?
goji, in your example, is a package. Not a variable.
You cannot pass packages around like this.
If you look at the example on the goji github page
You simply just call goji.Get from your Init function, and goji.Serve from your main
route.go
package route
import "route"
import "github.com/zenazn/goji"
func Init(){
goji.Get("/hello/:name", hello)
}
main.go
package main
import "github.com/zenazn/goji"
func main(){
route.Init()
goji.Serve()
}
Packages in go export constants, variables, types and functions that have uppercase letters as their name. The package itself is not something directly manipulatable by the program.
The package goji should be exporting a variable named something like goji.Goji if you want to directly access it from other packages. A better solution is to provide some functions in the package that allow you to register your functions/helpers.
You could also export a function from goji like:
func Set(s string, func(w http.ResponseWriter, r *http.Request)) { ... }
that could be used by other packages:
goji.Set("/static", myFunc)
The error you had "use of package goji without selector" is saying you can't use the name of the package without specifying which exported value you want from the package. It's expecting goji.something not goji by itself.
The function init() inside go files has special properties: see http://golang.org/ref/spec#Program_initialization_and_execution

Package imports, cannot use struct from imported package

This is probably a noob mistake but I cannot figure this out.
In main.go I am importing a package.
import(
"models/users"
)
// ...
func main() {
r.HandleFunc("/users/list", UsersModel.List())
The package is stored in src/models/users
The users package looks like this:
package users
import (
"gopkg.in/mgo.v2"
)
// ...
/**
* User Model
*/
type UsersModel struct {
}
// Add methods to the UsersModel type.
func (m *UsersModel) List() {
// ...
When I run the code I get the following error.
src\main.go:9: imported and not used: "models/users" src\main.go:20:
undefined: UsersModel
The go code appears to be valid as if I invalidate it throws an error. How do I export the UsersModel type from the users package?
You need to prefix your use of UsersModel with the package name users, like so:
um := users.UserModel{}
UsersModel.List() is also wrong: go doesn't have "static methods" or "class methods".

Resources