Call function in another package

This is asked many times before, but I just want an explanation why it does not work.

src
  |—main
     |–mail – main.go
     |–main.go

I want to call a function from main.go in mail/main.go

This works. WHY?:

import (
	mail "./mail"
	"fmt"
)

But WHY does not this work?

import (
	"main/mail"
	"fmt"
)

cannot find package “main/mail” in any of:
/usr/local/go/src/main/mail (from $GOROOT)
/Users/sibert/go/src/main/mail (from $GOPATH)

The path is correct AFAIK.

I am looking for an explanation how it works rather than a solution.

1 Like

This becomes a case of circular dependency and it is not allowed.

A way to call your function is to reduce coupling with your entry-point package i.e: main.

For example, you can move your function to mail.go:

mail/mail.go

package mail

func SomeFunc() {
    fmt.Println("I'm doing something")
}

and inside main.go you can call like this

package main

import "mymodule/mail"

func main() {
    mail.SomeFunc()
}

this is totally fine.


For this part of the error:

Go is not able to find the mail package that is inside your project folder,
try importing projectName/mail instead of mail or main/mail. (Replace projectName with your folder name where the main.go is in)

1 Like

If I interpret you correct, this should be the folder structure?

structure

Using this

import (
	"fmt"
	"web/mail"
)

Gives this error when go build:

cannot find package “web/mail” in any of:
/usr/local/go/src/web/mail (from $GOROOT)
/Users/sibert/go/src/web/mail (from $GOPATH)

What am I doing wrong?

1 Like

May be you should use path from github.com

ie: import “github.com/web/mail

create your username in github.com folder, and put your project in that folder, this will give you better folder structure.

like: github.com/your_username/project_folder

1 Like

I am not using github yet. So I have the go files locally…

1 Like

For some reason this do not work.

import (
"mymodule/mail")

But this works

import (
"../mail")

Anybody who can explain this to me?

1 Like

I’ve done a little digging and something seems weird about your situation…
Could you share your project structure, output from go env and the top of your .go files?

On a hunch I would think something with your go workspace setup is amiss, eg your mentioned “src” folder is not actually in your GOPATH. That would at least explain every error message so far.

1 Like

go env

GOARCH=“amd64”
GOBIN=""
GOCACHE="/Users/sibert/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH=“amd64”
GOHOSTOS=“darwin”
GOOS=“darwin”
GOPATH="/Users/sibert/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO=“gccgo”
CC=“clang”
CXX=“clang++”
CGO_ENABLED=“1”
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG=“pkg-config”
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/s5/8y4xhk5d5kq1rbd5r3mk4lzw0000gn/T/go-build619608189=/tmp/go-build -gno-record-gcc-switches -fno-common"

main:

package main

import (
	"../mail"
	"fmt"
	"html/template"
	"net/http"
	"strings"
)

mail:

package mail

    import (
    	"log"
    	"net/smtp"
    )
1 Like

Thank you.
I’m afraid I can’t answer your question because afaik it should not work like that, and I can’t replicate your results.

You are correct in that import paths should be absolute, unique identifiers in some go work-space.
i.e. import some/thing looks in all $GOPATH/src/some/thing
And absolute as in not relative, that’s why you import main/mail and not just mail (or ./mail for that matter), even though it is a subpackage of your current package.

You can use relative paths for imports, but as far as I can tell that is only supposed for projects not in a go work-space, and if you are in a work-space it throws the error local import "./mail" in non-local package. (see here)

That’s why my guess was that your files are not in your GOPATH, then go would not be able to find it (hence the cannot find package error), but would allow the use of relative paths (no local import in non-local package error). But from your information everything looks ok.
I am sorry I can’t be of further help.

//edit as a side note:
You can use remote paths (eg github.com) locally, even if they’re not actually hosted there. They are only special in that they tell go get how to obtain them if not locally available (yet). The compiler will not care about all that and only use the local version (or fail if not there). But that does not help your original question.

1 Like

How should you work if you not are using Github?

1 Like

As far as I can tell, exactly as you are (or were in your first post).
Also, I can recommend This Read.

My comment was that I do not know why things work or don’t work for you the way you describe in your first post, because they shouldn’t behave like that (it should be the other way around). So something weird is going on for you that I cannot identify.

Regarding “when not using Github”: Probably forget about it.
It is completely irrelevant (for your usecase) if your project is in src/github.com/yourname/yourproject or in src/yourproject
You’ll find some recommend putting your projects in src/github.com/yourname/ even if you’re developing just local, but they are usually assuming you might upload your code at some point in the future; then you’d have to change all imports in other projects. But if that does not apply to you, you can safely ignore it (unless I’m missing something).

1 Like

Relative imports is not allowed in $GOPATH/src, you say it works and it means you may not under go workspace? And what is the installed go version?

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.