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

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

Related

Doesn't see public functions of a struct Golang

I don't see the public method of the struct that I defined.
Can someone please let me understand why?
Here is the code:
// DataSaver.go:
package DataStorage
import (
"fmt"
"os"
)
type DataSaver struct {
// doesn't relevant to my question
fileName string
file *os.File
}
func PrintStr() {
fmt.Println("hello")
}
Then, I have a main method in other class. I initialized the struct and I wanted to call to PrintStr() function. However, I can't call to this method. Why?
Thank you!
That is not a method, it is just a function.
Import DataStorage (you should make it lower case) then you can call DataStorage.PrintStr()
I had a play around myself with this, and there are a few things to be careful of:
Make sure you import the package properly with respect to your GOPATH, e.g.
import "github.com/some-repo/datastorage"
And ensure that your packages/repos are in your GOPATH and in the correct directories (go is very fussy about how you do this)
Refer to your function using the package name like so:
func main(){
DataStorage.PrintStr()
}
The other poster is correct in that go conventions are to keep package names in lowercase.
Seems you dont have the concept of method receiver yet. Your method for the struct should be defined as below :
func (this DataSaver)PrintStr() {
fmt.Println("hello")
}
or
func (this *DataSaver)PrintStr() {
fmt.Println("hello")
}
which one you choose depends on you want to call the method on a pointer or not;

Two go files having package declaration main inside a package

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

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

Resources