Error in importing custom packages in Go Lang - go

I have created a library by the name libfastget which is in the src with my program as
src
|-libfastget
| |-libfastget.go
|
|-MainProgram
|-main.go
and the libfastget exports a funtion fastget as follows
package libfastget
import (
"fmt"
"io"
)
func fastget(urlPtr *string, nPtr *int, outFilePtr *string) download {
.....
return dl
}
When I use the library in my main program
package main
import (
"fmt"
"net/http"
"os"
"libfastget"
"path/filepath"
"strings"
"flag"
"time"
)
func uploadFunc(w http.ResponseWriter, r *http.Request) {
n:=libfastget.fastget(url,4,filename)
}
}
I get the following error upon trying to build with go build
# FServe
./main.go:94: cannot refer to unexported name libfastget.fastget
./main.go:94: undefined: libfastget.fastget
The strange thing is that the library file libfastget.a is present in the pkg folder.

you would need to make your function exportable with an uppercase for its name:
func Fastget(...
Used as:
n:=libfastget.Fastget(url,4,filename)
The spec mentions: "Exported identifiers":
An identifier may be exported to permit access to it from another package. An identifier is exported if both:
the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and
the identifier is declared in the package block or it is a field name or method name.
All other identifiers are not exported.

to export a function into another package the function identifier must start with a capital letter.

I recently started learning GO Lang (2 days back)
And what I found was you need to setup a workspace folder to make the local packages import into other projects or main.go files. I'm using VS Code editor. Please correct me if Im wrong, but this setup works fine for me.
Inside your bash_profile OR .zshrc file add below lines, update the GOPATH as per your folder path.
export GOPATH=~/projects/GO_PROJECTS
export PATH=$PATH:$GOPATH/bin:$PATH
and this is my sayHello.go file, please note to be able to export a function the func name should start with a CapitalCase SayHello
package utils
import "fmt"
func SayHello() {
fmt.Println("Hello, Ajinkya")
}
and now I am able to import utils package into main.go file
package main
import (
"go_proj1/utils"
)
func main() {
utils.SayHello()
}

set the current directory as GOPATH
or you can use local import as follows
move your main.go to the ../ directory to the libfastget.go.
i mean the files looks like:
src
|-libfastget
| |-libfastget.go
|
|-main.go
import "./libfastget"

Related

I can't import "cloud.google.com/go/datastore"

I can't understand why this :/
I tried go get -u ** with every url that I found.
Thanks
Golang:
$ go version
go version go1.13.3 windows/amd64
Source test:
package main
import (
"fmt"
"cloud.google.com/go/datastore"
)
var client *datastore.Client
func main() {
fmt.Println("Work")
}
Error:
$ go run main.go
# google.golang.org/grpc/internal/transport
..\..\..\..\google.golang.org\grpc\internal\transport\http_util.go:270:23: cannot use hf (type "vendor/golang.org/x/net/http2/hpack".HeaderField) as type
"golang.org/x/net/http2/hpack".HeaderField in argument to d.processHeaderField
..\..\..\..\google.golang.org\grpc\internal\transport\http_util.go:675:23: cannot use "golang.org/x/net/http2/hpack".NewDecoder(http2InitHeaderTableSize,
nil) (type *"golang.org/x/net/http2/hpack".Decoder) as type *"vendor/golang.org/x/net/http2/hpack".Decoder in assignment
Go requires you make use of any package that you import. In this case you are importing "cloud.google.com/go/datastore" but not doing anything with it. The global variable that you declared is also not being used. Since it seems you are just trying to test, so I would recommend you do something with it (atleast print it). Like-
package main
import (
"fmt"
"cloud.google.com/go/datastore"
)
var client *datastore.Client
func main() {
fmt.Println(client)
}

Golang local import

I am attempting to do a local import but it fails.
My environment is:
echo $GOPATH
/home/peter/go
echo $GOROOT
/usr/local/go
The entry point is:
/home/peter/go/src/projects/pkgs1/main.go
The imported file is:
/home/peter/go/src/projects/pkgs2/stuff.go
main.go
package main
import (
"fmt"
"projects/pkgs2" // <- this does not resolve
)
func main(){
fmt.Println("123")
pkgs2.X()
}
stuff.go
package pkgs2
import "fmt"
func X(){
fmt.Println("X")
}
Any pointers on what I do wrong?
Your import path is correct and should resolve successfully, but as written, your program won't compile because the import isn't being used and there is no local function named x.
As mentioned by mkopriva your x function in pkgs2 isn't exported and you have not qualified it when trying to use it in your main package.
To export a function, it needs to start with a capital letter.
To use the function in another package, you need to prefix the package name to the function name.
main.go
package main
import (
"fmt"
"projects/pkgs2"
)
func main(){
fmt.Println("123")
pkgs2.X()
}
stuff.go
package pkgs2
import "fmt"
func X(){
fmt.Println("X")
}

import code from a separate package/folder [duplicate]

This question already has an answer here:
Imported struct from other package is undefined
(1 answer)
Closed 4 years ago.
I have this directory layout:
/baba
biz.go # package baba
/hello
foo.go # package main
biz.go looks like this:
package baba
func Foodd(z int) int {
return z + 5
}
and foo.go looks like this:
package main
import (
"fmt"
"log"
)
func main() {
log.Fatal(Foodd(3))
}
currently this doesn't compile because Foodd is not recognized. How do I import the baba package in foo.go?
I assume if I compile like so, that it will pull in the right files:
go build foo.go
Or do I need to include the files in the baba package in the go build command? (I would hope not).
You need to import the baba package in order to use it from your main package. That will look something like:
package main
import (
"fmt"
"log"
"github.com/the1mills/myproject/baba"
)
func main() {
log.Fatal(baba.Foodd(3))
}
Imported packages are referred to by their package name, which is usually, but not always, the last element of the import path.
Usually, people let goimports handle finding the correct import path and automatically adding it. Your editor of choice probably has goimports integration.
Also see this answer for some other references and how to set up your directory structure.

My main.go file cannot see other files

I need some help understanding what is wrong with my file layout in a simple web application.
$GOPATH/src/example.com/myweb
I then have 2 files:
$GOPATH/src/example.com/myweb/main.go
$GOPATH/src/example.com/myweb/api.go
Both files have:
package main
The api.go file looks like:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type API struct {
URI string
Token string
Secret string
client *http.Client
}
...
My main.go file looks like:
package main
import (
"github.com/gorilla/mux"
"html/template"
"net/http"
)
var (
templates = template.Must(template.ParseFiles("views/home.html", "views/history.html", "views/incident.html"))
api = API{
URI: "http://localhost:3000",
Token: "abc",
Secret: "123",
}
)
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
..
..
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
..
..
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
r.PathPrefix("/assets/").Handler(
http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))))
http.ListenAndServe(":9000", r)
}
In the code I excluded, I basically use structs that are defined in my api.go file, and I get this error when doing:
go run main.go
# command-line-arguments
./main.go:16: undefined: API
./main.go:23: undefined: User
What exactly am I doing wrong here?
I tried changing the package name in api.go to myweb but that didn't help.
Am I suppose to use the package name myweb? Is just 1 file suppose to have main?
You're compiling only the main.go file. You should use:
go run main.go api.go
Or:
go run *.go
If you're writing a complex application, you might add everything to packages in subdirectories and have a single main.go file. For instance, etcd has an etcdmain subdirectory/package along with other subdirectories/packages. Something like:
/alarm
/auth
/cmd
/etcdmain
...
And the main.go file is simply:
package main
import "github.com/coreos/etcd/etcdmain"
func main() {
etcdmain.Main()
}
You are using golang workspace project, which is good for the structure for your application and it also standardize.
When we use the golang workspace, you can not run single go file. You need to call go build / go install.
Install
go install example.com/myweb
The command above will compile your main package on example.com/myweb. And the myweb executable binary will be placed on the GOPATH/bin. And you can run it manually.
Build
go build example.com/myweb
The command is similar to go install but the binary executable file will be placed on the current directory when you call the command, instead of on GOPATH/bin (unless your current directory is GOPATH/bin).
For more information please check this link.

Call a function from another package in Go

I have two files main.go which is under package main, and another file with some functions in the package called functions.
My question is: How can I call a function from package main?
File 1: main.go (located in MyProj/main.go)
package main
import "fmt"
import "functions" // I dont have problem creating the reference here
func main(){
c:= functions.getValue() // <---- this is I want to do
}
File 2: functions.go (located in MyProj/functions/functions.go)
package functions
func getValue() string{
return "Hello from this another package"
}
You import the package by its import path, and reference all its exported symbols (those starting with a capital letter) through the package name, like so:
import "MyProj/functions"
functions.GetValue()
You should prefix your import in main.go with: MyProj, because, the directory the code resides in is a package name by default in Go whether you're calling it main or not. It will be named as MyProj.
package main just denotes that this file has an executable command which contains func main(). Then, you can run this code as: go run main.go. See here for more info.
You should rename your func getValue() in functions package to func GetValue(), because, only that way the func will be visible to other packages. See here for more info.
File 1: main.go (located in MyProj/main.go)
package main
import (
"fmt"
"MyProj/functions"
)
func main(){
fmt.Println(functions.GetValue())
}
File 2: functions.go (located in MyProj/functions/functions.go)
package functions
// `getValue` should be `GetValue` to be exposed to other packages.
// It should start with a capital letter.
func GetValue() string{
return "Hello from this another package"
}
Export function getValue by making 1st character of function name capital, GetValue
you can write
import(
functions "./functions"
)
func main(){
c:= functions.getValue() <-
}
If you write in gopath write this import functions "MyProj/functions" or if you are working with Docker
In Go packages, all identifiers will be exported to other packages if the first letter of the identifier name starts with an uppercase letter.
=> change getValue() to GetValue()
you need to create a go.mod file in the root directory of your project: go mod init module_name
the name of exposed function should start with capital letter
import(
"module_name/functions"
)
func main(){
functions.SomeFunction()
}

Resources