How to use self defined package - go

I have follow two simple go files
main.go
package main
import "fmt"
import "go-package/math"
func main() {
xs := []float64{1, 2, 3, 4}
avg := math.Average(xs)
fmt.Println(avg)
}
mymath.go
package math
func Average(xs []float64) float64 {
total := float64(0)
for _, x := range xs {
total += x
}
return total / float64(len(xs))
}
The file and directory structure is:
$GOPATH
src
go-package
math
mymath.go
main.go
When I navigate to $GOPATH/src/go-package, and open the terminal and run the command: go run main.go, the result is printed out.
Then, I navigate to $GOPATH/src/go-package/math, and run the command go install, and the package successfully installed at $GOPATH\pkg\windows_amd64\go-package\math.a
Then I navigate back to $GOPATH/src/go-package, and remove the math directoy,
I rerun the command go run main.go, error occurs:
main.go:4:8: cannot find package "go-package/math" in any of:
D:\softwareInstalled\Go\src\go-package\math (from $GOROOT)
D:\softwareInstalled\Go\GoPath\src\go-package\math (from $GOPATH)
I have put the math package at $GOPATH\pkg\windows_amd64\go-package\math.a
I wonder why Go doesn't pick up the package from this directory.
And how can I use math.a?Where should I place it?

Golang uses the source files of your imported packages. So when you wanna use the package go-package/math inside your main.go, you should not delete the source files from src/go-package/math. Leave them inside your project and everything's good.
Besides, go get also loads source files into your $GOPATH/src folder. Hope this helps.

Related

Go package not in $GOROOT

I'm using the following Go module to build an application:
github.com/martinlindhe/unit
Right now, the Go code is very simple; I'm just trying to get the environment set up for the real work:
import(
"fmt"
"unit"
)
foo := unit.FromFahrenheit(100)
fmt.Println("100 fahrenheit in celsius = ", foo.Celsius())
In go.mod:
go 1.17
require github.com/martinlindhe/unit v0.0.0-20210313160520-19b60e03648d
Executing either go build or go get results in:
package unit is not in GOROOT (/usr/local/Cellar/go/1.17/libexec/src/unit)
Running go mod download executes without error. The go.sum file seems to be correct, all the necessary dependencies exist.
The environment is the latest version of VS Code, Go installed via homebrew on MacOS Big Sur 11.5.2
There must be something obvious I'm missing. I've not had this problem with other apps I've written.
The import path is not right. Playground.
package main
import (
"fmt"
"github.com/martinlindhe/unit"
)
func main() {
foo := unit.FromFahrenheit(100)
fmt.Println("100 fahrenheit in celsius = ", foo.Celsius())
}

Use run test in VS Code Go extension tries to run tests in package main

Hi I am using Go version 1.16:
$ go version
go version go1.16.2 darwin/amd64
# .zshrc
#
# Go Setup
export GOPATH="$HOME/go"
export PATH=$PATH:$GOPATH/bin
and have this setup:
tree ./
./
├── go.mod
├── sum.go
└── sum_test.go
// go.mod
module mysum
go 1.16
// sum.go
package mysum
func Sum(numbers [5]int) int {
sum := 0
for _, number := range numbers {
sum += number
}
return sum
}
// sum_test.go
package mysum
import "testing"
func TestSum(t *testing.T) {
numbers := [5]int{1, 2, 3, 4, 5}
got := Sum(numbers)
want := 15
if got != want {
t.Errorf("got %d want %d given, %v", got, want, numbers)
}
}
And when I click run test (above function TestSum) in below screenshot, I got an error says:
Running tool: /usr/local/go/bin/go test -timeout 30s -run ^TestSum$ main
package main is not in GOROOT (/usr/local/go/src/main)
If I manually run go test -run ^TestSum$ in the folder it works fine:
$ go test -run ^TestSum$ mysum
PASS
ok mysum 0.005s
Does anyone know if I miss any configuration for Go with VS Code?
How do I tell the extension to run tests in mysum package instead of main package?
$ /usr/local/go/bin/go test -timeout 30s -run ^TestSum$ mysum
Go extension v0.23.2, VS Code Version: 1.54.2
Have you changed the module name in go.mod from main to mysum before running 'run test'? Are you still seeing an issue if you reload the window? (Cmd+Shift+P -> "Developer: Reload Window")
I found an issue in the current go extension https://github.com/golang/vscode-go/issues/1373 but I am not yet sure if this is the same issue you are seeing.
(sorry - I meant to add as a comment, but I don't have enough credit to add my reply as a comment :-))

How to use statistical function (MannWhitneyUTest) from go internal packages

I am trying to run Mann-Whiteney-U test with following code:
package main
import (
"fmt"
"stats"
)
func main() {
e, _ = MannWhitneyUTest([]float64{1, 2, 3, 4, 5},
[]float64{1, 2, 3, 5, 6},
0)
fmt.Println("Mann-WhitneyUTest: ", e)
}
However, this gives me this error:
$ go run mainstats2.go
mainstats2.go:5:2: cannot find package "stats" in any of:
/usr/local/go/src/stats (from $GOROOT)
/home/iuser/go/src/stats (from $GOPATH)
I have following stats packages installed:
$ go list all | grep stats
github.com/montanaflynn/stats
github.com/montanaflynn/stats/examples
golang.org/x/perf/internal/stats
golang.org/x/perf/vendor/github.com/aclements/go-moremath/stats
golang.org/x/perf/vendor/google.golang.org/grpc/stats
I need stats package golang.org/x/perf/ which I had installed by command: go get golang.org/x/perf/internal/stats
I believe this package is already there in go installation and was not needed to be installed separately.
How do I solve this problem? Thanks for your help.
The error occurs because your import path is incorrect, it should be:
import (
"fmt"
"golang.org/x/perf/internal/stats"
)
But even though import path issue is fixed, you'll get another error for trying to use internal package.
stats.go:4:5: use of internal package golang.org/x/perf/internal/stats not allowed
I suggest try to find another alternative library.
EDIT #1:
If you insist, there is a workaround. Try to copy the $GOPATH/src/golang.org/x/perf/internal/stats folder directly into your project, then import it. It worked, please see screenshot below.
EDIT 2:
I have copied the folder to ~/go/src/stats. It is still not working. What should I put for import. Currently it is just "stats"
I think you are doing it wrong. First, you need to create what-so-called project, it's a folder placed inside $GOPATH/src.
For example in image below I created a project called my-example-app, placed under $GOPATH/src. So the full path of the project will be $GOPATH/src/my-example-app.
Inside my project, I created main.go file. This file contains the code (I copied from yours).
Also, I copied the $GOPATH/src/golang.org/x/perf/internal/stats folder into my project, so the stats folder will be on the same level with my main.go.
The import of stats folder need to be happen relative to the project name, so the correct import path would be:
import "my-example-app/stats"
Here is content of my main.go (copied from yours with some syntax error fix addition).
package main
import (
"fmt"
"my-example-app/stats"
)
func main() {
e, _ := stats.MannWhitneyUTest([]float64{1, 2, 3, 4, 5},
[]float64{1, 2, 3, 5, 6},
0)
fmt.Println("Mann-WhitneyUTest: ", e)
}

how to copy non-go files in with go mod

go mod does not include the non-go code in the vendor directory.
Currently we are using go with go-oracle to connect to the database. We are planning on using docker so went with the idea of using go modules to version-ize our project. But since go-oracle has sub folders which have C code, it does not get copied over from the mod directory that go creates in the pkg folder. Is there a way we could add the non go code as well? We did try to use https://github.com/goware/modvendor but it did not copy the non-go code. Unless we did not use it correctly.
package main
import (
"fmt"
"github.com/jmoiron/sqlx"
log "github.com/sirupsen/logrus"
goracle "gopkg.in/goracle.v2"
)
const connectionString = "some connection string"
func main() {
fmt.Print("Inside main")
db, err := sqlx.Connect("goracle", connectionString)
if err != nil {
log.Infof("Could not connect %v%", err)
} else {
db.Query("select 1 from dual")
}
fmt.Println(goracle.DriverName)
}
go mod init
go mod vendor
You will see that the code will not compile.
I believe your issue is that you did not set a module path for your package. Details on my actions to build your code below:
After creating a test package gomod-test in my /tmp folder, I ran:
go mod init tmp/gomod-test // <-- this is the module path
go mod vendor
which pulled in the required dependencies including gopkg.in/goracle.v2 inside of ./vendor/goracle.v2/. I was then able to build the "project" using
go build main.go

"go run" but notice me missing .a file (I have run "go get")

I want to run a go file, main package imported a local package which imported a github package. and get an error (missing .a file)
ENV:
$GOROOT=/usr/local/go
$GOPATH=/gopath
go version 1.6.3 (same problem in 1.6.2)
I tried to run a go file like this:
/gopath/src/myproj/main/app.go
package main
import (
"../http/server"
)
func main() {
server.Run()
}
/gopath/src/myproj/http/server/route.go
package server
import (
"github.com/gorilla/mux"
"net/http"
)
func Run(){
router := mux.NewRouter()
router.HandleFunc("/", handler)
http.Handle("/", router)
http.ListenAndServe("9090", nil)
}
func handler(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello"))
}
then,I run go get github.com/gorilla/mux and I can see there are files
/gopath/pkg/linux_amd64/github.com/gorilla/mux (there are context.a and mux.a)
/gopath/src/github.com/gorilla/mux
/gopath/src/github.com/gorilla/context
Yes, src file and pkg file(.a) has downloaded form github,
BUT , I run "go run main/app.go" , get
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: cannot open file /usr/local/go/pkg/linux_amd64/github.com/gorilla/mux.a: open /usr/local/go/pkg/linux_amd64/github.com/gorilla/mux.a: no such file or directory
compiler does not find file in GOPATH, but GOROOT
if I copy $GOPATH/pkg files to $GOROOT/pkg was good.
And, if I import github.com/gorilla/mux in main package directly was fine too.
As JimB said don't use relative paths for imports
if you change "../http/server" to myproj/http/server it shouldn't have the linking problems anymore

Resources