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())
}
Related
I am using golang in my project.
The code is as follows
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"sync"
"time"
)
....
if response.StatusCode != 200 {
respBdy, _ := io.ReadAll(response.Body)
return fmt.Errorf("%v response from client: %v", response.StatusCode, respBdy)
}
When i run the project using make run, i am getting the following error
go-tools#v0.0.0-20220528203058-9108e3643722/messengers/client.go:133:17: undefined: io.ReadAll
On debugging, i can understand the problem is ReadAll not declared by package iocompiler
Any idea on how to fix this?
Edit: The go version i am using is
go version
go version go1.15.6 darwin/amd64
As Manjeet and Emile stated, starting from go1.16's release, the functions from io/ioutil are moved to io package.
Discard => io.Discard
NopCloser => io.NopCloser
ReadAll => io.ReadAll
ReadDir => os.ReadDir
ReadFile => os.ReadFile
TempDir => os.MkdirTemp
TempFile => os.CreateTemp
WriteFile => os.WriteFile
Linking release notes of go1.16 for reference.
About the mismatch of go versions: go1.13 in go.mod and go1.15 in terminal, the go version in go.mod gets added depending on the version when it was initialised using go mod init [module-path]. GoDoc page for go mod init doesn't clear your doubt but attaching for ref.
In other words, the go.mod doesn't denote your local go version. Rather, it gives the minimal go version and imported package's versions that will let your project (as module) run hassle-free.
I found a sample from an old project. Will try to explain on it.
module project-name
go 1.14
require (
github.com/go-redis/redis/v7 v7.4.0
github.com/stretchr/testify v1.6.1
github.com/vektra/mockery v1.1.2 // indirect
)
This means the project requires go1.14, along with redis#v7.4.0, testify#v1.6.1 and mockery#v1.1.2 at the very least. Lower than these versions "might" still work. Not recommended. Higher than those versions are expected to be better, but there is a possibility of change of names or package name like above. More details at gomod-ref.
Just another bit of info: the io and io/util are part of Go's standard library. This means that in order to use the function as io.ReadAll, you would need higher version of standard library, and so, higher version of Go (1.16 at least).
Conclusion: You can still keep go1.13 in go.mod. Just upgrade the go version in local. And if other devs are kind enough to let you upgrade in go.mod too, do it!
Opinion: I personally recommend go1.17's latest for now until all external packages implement go1.18 and generics.
New to Go/Golang and am trying to understand its package/dependency management system a little better.
I cloned this simple web service repo off GitHub and tried running it with go run main.go. In that main.go file:
package main
import (
"log"
"net/http"
"strconv"
"github.com/wpferg/services/httpHandlers"
"github.com/wpferg/services/storage"
"github.com/wpferg/services/structs"
)
const PORT = 8080
var messageId = 0
func createMessage(message string, sender string) structs.Message {
messageId++
return structs.Message{
ID: messageId,
Sender: sender,
Message: message,
}
}
func main() {
log.Println("Creating dummy messages")
storage.Add(createMessage("Testing", "1234"))
storage.Add(createMessage("Testing Again", "5678"))
storage.Add(createMessage("Testing A Third Time", "9012"))
log.Println("Attempting to start HTTP Server.")
http.HandleFunc("/", httpHandlers.HandleRequest)
var err = http.ListenAndServe(":"+strconv.Itoa(PORT), nil)
if err != nil {
log.Panicln("Server failed starting. Error: %s", err)
}
}
When I run this (run go main.go) I get:
main.go:8:2: cannot find package "github.com/wpferg/services/httpHandlers" in any of:
/usr/local/go/src/github.com/wpferg/services/httpHandlers (from $GOROOT)
/Users/myuser/go/src/github.com/wpferg/services/httpHandlers (from $GOPATH)
main.go:9:2: cannot find package "github.com/wpferg/services/storage" in any of:
/usr/local/go/src/github.com/wpferg/services/storage (from $GOROOT)
/Users/myuser/go/src/github.com/wpferg/services/storage (from $GOPATH)
main.go:10:2: cannot find package "github.com/wpferg/services/structs" in any of:
/usr/local/go/src/github.com/wpferg/services/structs (from $GOROOT)
/Users/myuser/go/src/github.com/wpferg/services/structs (from $GOPATH)
So it seems Go supports a way of "fetching" other packages from GitHub via HTTP but for some reason when I run it locally, its expecting the packages to be local.
What can I do to fix this so that the other packages are resolved? Why is Go looking for them locally instead of fetching them via the URL?
Problem is that this repo is from pre go modules era and doesn't use any dependency management system. Easiest way to fix it is to try to initialize it as module(if you use go < 1.14 set environment variable GO111MODULE=on):
go mod init github.com/wpferg/services
And then run:
go run main.go
it will resolve it's dependencies automatically and try to start the program.
P.S. But, regarding that it's an older code and it's unclear with what golang version(and packages versions) it was written it's likely that it will not work or, in some way, will be broken.
In my case, imports worked for a long time, then suddenly didn't.
I fixed it by running go mod tidy in the console.
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.
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
With halfdans advice, I was successfully able to use goinstall github.com/hoisie/web.go without any errors after installing git first. However, now when I try to compile the sample code given, go is not finding the web package. I get the error,
main.go:4: can't find import: web
On this code
package main
import (
"web"
)
func hello(val string) string { return "hello " + val }
func main() {
web.Get("/(.*)", hello)
web.Run("0.0.0.0:9999")
}
Is there something special I need to do in order for it to recognize the package? I found the package source at $GOROOT/src/pkg/github.com/hoisie/web.go/web. I tried github.com/hoisie/web.go/web as the import and it still did not like that.
If you install web.go through goinstall, you need to do:
import "github.com/hoisie/web.go"
Goinstall is still an experimental system. It would be nice if you didn't have to include the full path.
import web "github.com/hoisie/web.go"