skip to Main Content

I am doing a exercises for creating a module and then accessing global variable through main package.
tutorial at: https://www.golinuxcloud.com/golang-access-variable-from-another-package/

mkdir -p goexamples/global-vars
$ cd goexamples/global-vars
$ touch main.go
$ mkdir util
$ touch util/common.go
$ go mod init global-vars
go: creating new go.mod: module global-vars
go: to add module requirements and sums: go mod tidy
$ go mod tidy
$ cat go.mod 
module global-vars
go 1.20
$ cd .. 
tree .
 .
 └── global-vars
     ├── go.mod
     ├── main.go
     └── util
      └── common.go

I will try to access variable from common package into main package.
Here is the content of util/common.go

package util

var Mypath string    <<< global variable

func init() {
    Mypath = "/tmp"
}

Content of main.go:

package main

import (
  "fmt"
  "global-vars/util"
)

func main() {
    fmt.Println("The path is: " + util.Mypath)
}

when I try to run:

PS C:UsersShawngovsCodeExamStudy_Gogoexamplesglobal-vars> go run main.go

I’ll get the error saying:

go: module golang.org/x/sys appears multiple times in workspace.

(vsCodeExam is the only workspace with both go.work & go.mod)

go.mod :

module golang.org/x/sys

go 1.17

go.work:

go 1.20

use (
   .
   ./DebuggingEx
   ./DebuggingEx/TestFiles
   ./DebuggingEx/go-debugging
   ./Study_Go
)

My GOPATH: C:UsersShawngo

Please tell me how to fix the problem since if you remember I am fairly new to Golang.

2

Answers


  1. Chosen as BEST ANSWER

    result of go env:

    set GO111MODULE=auto
    set GOARCH=amd64
    set GOBIN=
    set GOCACHE=C:UsersShawnAppDataLocalgo-build
    set GOENV=C:UsersShawnAppDataRoaminggoenv  
    set GOEXE=.exe
    set GOEXPERIMENT=
    set GOFLAGS=
    set GOHOSTARCH=amd64
    set GOHOSTOS=windows
    set GOINSECURE=
    set GOMODCACHE=C:UsersShawngopkgmod
    set GONOPROXY=
    set GONOSUMDB=
    set GOOS=windows
    set GOPATH=C:UsersShawngo
    set GOPRIVATE=
    set GOPROXY=https://proxy.golang.org,direct
    set GOROOT=C:Program FilesGo
    set GOSUMDB=sum.golang.org
    set GOTMPDIR=
    set GOTOOLDIR=C:Program FilesGopkgtoolwindows_amd64
    set GOVCS=
    set GOVERSION=go1.20.3
    set GCCGO=gccgo
    set GOAMD64=v1
    set AR=ar
    set CC=gcc
    set CXX=g++
    set CGO_ENABLED=1
    set GOMOD=C:UsersShawngovsCodeExamStudy_Gogo.mod
    set GOWORK=C:UsersShawngovsCodeExamgo.work
    set CGO_CFLAGS=-O2 -g
    set CGO_CPPFLAGS=
    set CGO_CXXFLAGS=-O2 -g
    set CGO_FFLAGS=-O2 -g
    set CGO_LDFLAGS=-O2 -g
    set PKG_CONFIG=pkg-config
    set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:UsersShawnAppDataLocalTempgo-build2630634851=/tmp/go-build -gno-record-gcc-switches
    

    Also I take your advise using the 'go run' only but I get an error shown below: PS C:UsersShawngovsCodeExamStudy_Go> go run go: no go files listed (surely there are two .go files in the study_go folder) but when I do: PS C:UsersShawngovsCodeExamStudy_Go> go run GoByExamples.go

    go: module golang.org/x/sys appears multiple times in workspace
    go: module golang.org/x/sys appears multiple times in workspace
    

    How do I put a unique name in the go.mod which has a entry of golang.org/x/sys? where my id of DarkSideOfTheMoon fits in? Should I delete the go.mod and just leave the go.work in the below folder ? C:UsersShawngovsCodeExam ??? (since go.work and go.mod shouldn't be in one folder. I think I should because looking at go env result there's one in GOMOD=C:UsersShawngovsCodeExamStudy_Gogo.mod and one in C:UsersShawngovsCodeExam
    Thanks


  2. I believe your issue is something like the following:

    You have a workspace (simplified):

    go 1.20
    
    use (
       ./DebuggingEx
       ./DebuggingEx/TestFiles
    )
    

    and in each folder a go.mod:

    DebuggingEx/go.mod:

    module golang.org/x/sys
    

    DebuggingEx/TestFiles/go.mod:

    module golang.org/x/sys
    

    So when Go loads the workspace it retrieves the two folders and detects that you have two modules called golang.org/x/sys (in fact, as golang.org/x/sys is a real module and likely imported from the standard library, a single module with this name is likely to cause issues!).

    Your first question should be "Do I need a workspace". Workspaces are great when you are working on a complicated app and editing multiple modules at the same time. However they do add some complexity and you probably don’t need one (so deleting the go.work may be an option). Until you understand how modules work (and import path standards) using a workspace is likely to cause unnecessary confusion.

    I suspect a second question should be "Do I need multiple go.mod files"? In your case I’d guess that the answer is "no". Put a single go.mod at the root of your folder and forget about it (well you may need to run go mod tidy and go get -u ./..." from time to time). You do not need a separate go.mod for each subfolder (there are occasions where this may be desirable but probably not worth worrying about now). Bear in mind that a module is "a collection of packages that are released, versioned, and distributed together" – so all of your code while learning can quite happily live within a single module (given that you are not releasing, versioning or distributing).

    Regardless of the above your module names (as used in go mod init name and module name) should be unique. They identify your module (and the fact that you might be importing golang.org/x/sys is irrelevant). Calling your module golang.org/x/sys will lead to issues because that is the name of an existing module (that will probably be needed!).

    Here is a sample module (called temp3) that uses golang.org/x/sys:

    module temp3
    
    go 1.20
    
    require golang.org/x/sys v0.10.0
    

    It’s the require line that declares that golang.org/x/sys is needed (and provides a minimum version).

    Using module names like temp3 is valid. However if you want to share your code it becomes an issue (someone else may well use the same name) and prevents the Go tooling from automatically getting the module (it does not know where to find temp3; unless you use a go.work). Because of this general practice is to use an import path that can "describe how to obtain the package source code using a revision control system such as Git or Mercurial" (e.g. github.com/DarkSideOfTheMoon/goexamples). You don’t have to do this when working locally but it’s a good habit to get into (as is using a version control system such as Git).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search