Call a function from another package in Go - 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()
}

Related

modifying imported functions in go

I could override the builtin print() function's behavior by defining another print() in scope, as in https://play.golang.org/p/Y2ly31oXU67
Is it possible in go to alter the behavior on-the-fly of an imported function, say fmt.Println()?
If you want to 'alter' a builtin function, look at the very fine monkey patch utility https://github.com/bouk/monkey (And pay attention to the warnings, it's only really useful in test functions, and I for one reject any prod code that imports that package)
Import a different package with name "fmt" and implement whatever functions you need in that package. Here's an example:
File go.mod:
module test
File main.go
package main
import (
"test/fmt"
)
func main() {
fmt.Println("Hello, playground")
}
File fmt/fmt.go:
package fmt
import (
"fmt"
"log"
)
func Println(format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
log.Printf(msg)
}
Run it on the playground.
The code in this answer does not modify the imported function as asked in the question.

Why function in my package is not working

I have put a small code file in $GOPATH which is ~/go/src. Here I have made a folder mysrc and there I have kept a file mytest.go, which is as follows:
package mytest
import ("fmt")
func myfn(){
fmt.Println("My own fn")
}
I try to import above code with following file:
package main
import ("mysrc")
main(){
myfn()
}
When I try to run above file, I get error:
# command-line-arguments
./useMyfn.go:3:1: syntax error: non-declaration statement outside function body
Where is the problem and how can it be solved? Thanks for your help.
Edit: I corrected the main fn to func main() but now the errors are:
# command-line-arguments
./useMyfn.go:2:9: imported and not used: "mysrc" as mytest
./useMyfn.go:4:2: undefined: myfn
You need to do few things
I suggest to use a package name that the name is same with the folder name.
The myfn() function need to be exported. How to do it: simply set the first character of the function name to uppercase.
package mysrc // <-- 1
import (
"fmt"
)
func Myfn() { // <-- 2
fmt.Println("My own fn")
}
The func keyword is required before main() statement.
To access a function from other package, you need to write down the package name before the function name. In this context it'll be mysrc.Myfn().
package main
import (
"mysrc"
)
func main() { // <-- 3
mysrc.Myfn() // <-- 4
}

GOSwagger implementation for imported packages

I'm created a project structure like,
main.go and foo/bar.go
In main.go, imported foo package and used as foo.functionName(). Now i need to write swagger document in bar.go. When i did, ended with the following error message,
unable to determine package for /PATH_TO_PROJECT/foo/bar.go
Ensure in foo/bar.go the package declared is package foo. Then the function you want to access in the main.go file should start with a capital letter. i.e.
foo/bar.go
package foo
// PrintBar with extra txt
func PrintBar(txt string) string {
return "bar with txt " + txt
}
Then in main.go
package main
import (
"fmt"
"github.com/username/project/foo"
)
func main() {
fmt.Println("in main.go")
fmt.Println(foo.PrintBar("from main.go"))
}
Try enabling Debug mode for swagger by adding DEBUG=1 in front of your swagger command. This should print you what are the paths considered.
If you look at the source code where this error is thrown, you will see this error only happens when file is not in the $GOPATH. Double check that you have the program under $GOPATH/src.

Error in importing custom packages in Go Lang

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"

How to call function from another file in Go

I want to call function from another file in Go. Can any one help?
test1.go
package main
func main() {
demo()
}
test2.go
package main
import "fmt"
func main() {
}
func demo() {
fmt.Println("HI")
}
How to call demo in test2 from test1?
You can't have more than one main in your package.
More generally, you can't have more than one function with a given name in a package.
Remove the main in test2.go and compile the application. The demo function will be visible from test1.go.
Go Lang by default builds/runs only the mentioned file. To Link all files you need to specify the name of all files while running.
Run either of below two commands:
$go run test1.go test2.go. //order of file doesn't matter
$go run *.go
You should do similar thing, if you want to build them.
I was looking for the same thing. To answer your question "How to call demo in test2 from test1?", here is the way I did it. Run this code with go run test1.go command. Change the current_folder to folder where test1.go is.
test1.go
package main
import (
L "./lib"
)
func main() {
L.Demo()
}
lib\test2.go
Put test2.go file in subfolder lib
package lib
import "fmt"
// This func must be Exported, Capitalized, and comment added.
func Demo() {
fmt.Println("HI")
}
A functional, objective, simple quick example:
main.go
package main
import "pathToProject/controllers"
func main() {
controllers.Test()
}
control.go
package controllers
func Test() {
// Do Something
}
Don't ever forget: Visible External Functions, Variables and Methods starts with Capital Letter.
i.e:
func test() {
// I am not Visible outside the file
}
func Test() {
// I am VISIBLE OUTSIDE the FILE
}
If you just run go run test1.go and that file has a reference to a function in another file within the same package, it will error because you didn't tell Go to run the whole package, you told it to only run that one file.
You can tell go to run as a whole package by grouping the files as a package in the run commaned in several ways. Here are some examples (if your terminal is in the directory of your package):
go run ./
OR
go run test1.go test2.go
OR
go run *.go
You can expect the same behavior using the build command, and after running the executable created will run as a grouped package, where the files know about eachothers functions, etc. Example:
go build ./
OR
go build test1.go test2.go
OR
go build *.go
And then afterward simply calling the executable from the command line will give you a similar output to using the run command when you ran all the files together as a whole package. Ex:
./test1
Or whatever your executable filename happens to be called when it was created.
Folder Structure
duplicate
|
|--duplicate_main.go
|
|--countLines.go
|
|--abc.txt
duplicate_main.go
package main
import (
"fmt"
"os"
)
func main() {
counts := make(map[string]int)
files := os.Args[1:]
if len(files) == 0 {
countLines(os.Stdin, counts)
} else {
for _, arg := range files {
f, err := os.Open(arg)
if err != nil {
fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
continue
}
countLines(f, counts)
f.Close()
}
}
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
countLines.go
package main
import (
"bufio"
"os"
)
func countLines(f *os.File, counts map[string]int) {
input := bufio.NewScanner(f)
for input.Scan() {
counts[input.Text()]++
}
}
go run ch1_dup2.go countLines.go abc.txt
go run *.go abc.txt
go build ./
go build ch1_dup2.go countLines.go
go build *.go
You can import functions from another file by declaring the other file as a module. Keep both the files in the same project folder.
The first file test1.go should look like this:
package main
func main() {
demo()
}
From the second file remove the main function because only one main function can exist in a package. The second file, test2.go should look like below:
package main
import "fmt"
func demo() {
fmt.Println("HI")
}
Now from any terminal with the project directory set as the working directory run the command:
go mod init myproject.
This would create a file called go.mod in the project directory. The contents of this mod file might look like the below:
module myproject
go 1.16
Now from the terminal simply run the command go run .! The demo function would be executed from the first file as desired !!
as a stupid person who didn't find out what is going on with go module
should say :
create your main.go
in the same directory write this in your terminal
go mod init "your module name"
create a new directory and go inside it
create a new .go file and write the directory's name as package name
write any function you want ; just notice your function must starts with capital letter
back to main.go and
import "your module name / the name of your new directory"
finally what you need is writing the name of package and your function name after it
"the name of your new dirctory" + . + YourFunction()
and write this in terminal
go run .
you can write go run main.go instead.
sometimes you don't want to create a directory and want to create new .go file in the same directory, in this situation you need to be aware of, it doesn't matter to start your function with capital letter or not and you should run all .go files
go run *.go
because
go run main.go
doesn't work.
Let me try.
Firstly
at the root directory, you can run go mod init mymodule (note: mymodule is just an example name, changes it to what you use)
and maybe you need to run go mod tidy after that.
Folder structure will be like this
.
├── go.mod
├── calculator
│ └── calculator.go
└── main.go
for ./calculator/calculator.go
package calculator
func Sum(a, b int) int {
return a + b
}
Secondly
you can import calculator package and used function Sum (note that function will have Capitalize naming) in main.go like this
for ./main.go
package main
import (
"fmt"
"mymodule/calculator"
)
func main() {
result := calculator.Sum(1, 2)
fmt.Println(result)
}
After that
you can run this command at root directory.
go run main.go
Result will return 3 at console.
Bonus: for ./go.mod
module mymodule
go 1.19
ps. This is my first answer ever. I hope this help.

Resources