How to include external file in Go? - go

I'm using LiteIDE for Go. I have a Go file located here:
/Users/username/go/src/src/Helper/Helper.go
When I include the file using:
import "../Helper"
I get this error:
can't load package: /Users/username/go/src/src/projectA/main.go:4:8:
local import "../Helper" in non-local package
Any ideas what I'm doing wrong?

You import packages by import path. For package Helper, located in $GOPATH/src/Helper/, use:
import "Helper"
While they can work in some cases, relative paths aren't supported by the go toolchain, and are discouraged.

Related

Use Absolute path instead for go "fmt" in import directive

This is an instructional question and not a procedural one as simply requiring "fmt" works just fine, but when with the hello world golang file I modify it as follows
package main
import "golang.org/fmt"
func main() {
fmt.Println("Hello, world")
}
I get in response:
go:3:8: no required module provides package golang.org/fmt; to add it:
go get golang.org/fmt
I can see the fmt package in /usr/local/go/src/fmt and it mirrors the files in https://golang.org/src/fmt/
I am probably very close in the above file, what is the correct absolute path that would work to include fmt ? Thank you!
The correct absolute import path for the package is fmt.
Relative import paths start with ./ or ../. The import path fmt is an absolute import path.
Remote import paths start with a domain name. The package does not have a remote import path.
The tool chain creates a unique package for each import path. If the application could refer to the source code for the fmt package using a remote import path, the package with the remote path will be different from the standard fmt package. Every aspect of the package is unique. The code is duplicated. There is a ScanState type for each package and these types cannot be used interchangeably.
The pp cache is duplicated. And so on.
In this case, fmt is the fully qualified path. Compare the fmt docs [1] with golang.org/x/text docs [2].
Go standard library does have a go.mod [3], but trying to import std/fmt doesn't work either.
https://pkg.go.dev/fmt
https://pkg.go.dev/golang.org/x/text
https://github.com/golang/go/blob/master/src/go.mod

Specify base package in protobuf compilation in golang

I've got golang package github.com/user/protoapp, in this package I have folder proto containing protobuf files.
github.com/user/protoapp
|-proto
|-proto/app1
|-proto/app2
proto files in app1 and app2 have corresponing packages app1 and app;
Proto file from proto/app1 is importing file from proto/app2 like import "app2/messages.proto"; after compillation in app1.pb.go it becomes import app2 and protoapp fails to compile. How do I make imports in *.pb.go files become import "github.com/user/protoapp/proto/app2" rather than import "app2"?
you need to make your import in your proto a fully qualified path like in Go:
instead of import "app2/messages.proto";
try import "github.com/user/protoapp/proto/app2/messages.proto";
Never specify the half path "/app2/messages.proto" it won't be work.
Specify the full import name
import "github.com/user/protoapp/proto/app2/messages.proto";
and
Do define with the package name
//if we does'nt add package we define it will show error
package messagedata;

Unable to import a package located in the same directory

I want to import in the current file or package other file located in the same project in a directory. I'm doing this:
import (
// "./dir1"
"/Users/my_name/my_project/dir1"
)
None of them works
1) Cloning into '/Users/my_name/go/src/github.com/github_username/github_project'...
fatal: could not read Username for 'https://github.com': terminal prompts disabled
2) package /Users/my_name/my_project/dir1: unrecognized import path "/Users/my_name/my_project/dir1" (import path does not begin with hostname)
How to import a directory located in the current project?
Import paths are not directly paths. They are relative to the GOPATH (found by doing echo $GOPATH).
This implies that go is very opinionated about where you store your code as well. So you will have to move your code to $GOPATH/src/my_name/my_project. If you are hosting your code on something like github then move it to $GOPATH/src/github.com/my_github_name/my_project.
Then when you import your sub-packages:
import "github.com/my_github_name/my_project"
Notice that it is not an absolute path.
Rename dir1 to to the same name as the package inside that directory, then you can import it with:
import "./package1"
However doing this is not recommended, use GOPATH instead. If you really don't want to use GOPATH, you may want to use Modules in Go 1.11 (but it is still experimental).
Make sure your project is in GOPATH's go/src folder(Recommended way). Then import like this
package logic
import (
"project_name/folder_name"
)

Accessing local packages within a go module (go 1.11)

I'm trying out Go's new modules system and am having trouble accessing local packages. The following project is in a folder on my desktop outside my gopath.
My project structure looks like:
/
- /platform
- platform.go
- main.go
- go.mod
// platform.go
package platform
import "fmt"
func Print() {
fmt.Println("Hi")
}
// main.go
package main
import "platform"
func main() {
platform.Print()
}
go build main.go tells me
cannot find module for path platform
Let me define this first modules are collections of packages. In Go 11, I use go modules like the following:
If both packages are in the same project, you could just do the following:
In go.mod:
module github.com/userName/moduleName
and inside your main.go
import "github.com/userName/moduleName/platform"
However, if they are separate modules, i.e different physical paths and you still want to import local packages without publishing this remotely to github for example, you could achieve this by using replace directive.
Given the module name github.com/otherModule and platform, as you've called it, is the only package inside there. In your main module's go.mod add the following lines:
module github.com/userName/mainModule
require "github.com/userName/otherModule" v0.0.0
replace "github.com/userName/otherModule" v0.0.0 => "local physical path to the otherModule"
Note: The path should point to the root directory of the module, and can be absolute or relative.
Inside main.go, to import a specific package like platform from otherModule:
import "github.com/userName/otherModule/platform"
Here's a gentle introduction to Golang Modules
I would strongly suggest you to use go toolchain which takes care of these issues out of the box. Visual Studio Code with vscode-go plugin is really useful.
Problem here is that Go requires relative paths with respect to your $GOPATH/src or module in import statement. Depending on where you are in your GOPATH, import path should include that as well. In this case, import statement must include go module path in go.mod
GOPATH
Assume your project resides here:
$GOPATH/src/github.com/myuser/myproject
Your import path should be:
import "github.com/myuser/myproject/platform"
VGO
Assume your go.mod file is:
module example.com/myuser/myproject
Your import path should be:
import "example.com/myuser/myproject/platform"
As someone new to go I didn't immediately understand the accepted answer – which is great, by the way. Here's a shorter answer for those very new people!
In go modules/packages are expressed as urls that you import in your code:
import your.org/internal/fancy_module
But wait! My code isn't at a url, what's happening??
This is the cleverness of go. You pretend there's a url even when there isn't one. Because:
This makes including easier as no matter where your file is located the import uses the same url (the code stays the same even if the files move!)
You can have packages that having naming conflicts. So google.com/go-api/user doesn't conflict with the definitions at your.org/internal/user
Someday you might publish a url on GitHub and all the code will just work
That's all great Evan, but how do I import a relative path?
Good question! You can import by changing your go.mod file to have this line:
module fancy_module
go 1.16
replace your.org/fancy_module => ../path/to/fancy_module
Given the Golang Project structure
/
- /platform
- platform.go
- main.go
- go.mod
To access the methods or structs...etc (which are public) from local packages of /platform is simple, shown below
// main.go
package main
import (
p "./platform"
)
func main() {
p.Print()
}
this should work

Building package structure with child-/sub-packages

I'm trying to make a simple calculator in Go. I'm designing it in such a way that I can build a command-line interface first and easily swap in a GUI interface. The project location is $GOPATH/src/gocalc (all paths hereafter are relative to the project location). The command-line interface logic is stored in a file gocalc.go. The calculator logic is stored in files calcfns/calcfns.go and operations/operations.go. All files have package names identical to their filename (sans extension) except the main program, gocalc.go, which is in the package main
calcfns.go imports operations.go via import "gocalc/operations"; gocalc.go imports calcfns.go via import "gocalc/calcfns"
To summarize:
$GOPATH/src/gocalc/
gocalc.go
package main
import "gocalc/calcfns"
calcfns/
calcfns.go
package calcfns
import "gocalc/operations"
operations/
operations.go
package operations
When I try to go build operations (from the project dir), I get the response: can't load package: package operations: import "operations": cannot find package
When I try go build gocalc/operations, I get can't load package: package gocalc/operations: import "gocalc/operations": cannot find package
When I try go build operations/operations.go, it compiles fine
When I try to go build calcfns or go build gocalc/calcfns, I get can't load package... messages, similar to those in operations; however, when I try to build calcfns/calcfns.go it chokes on the import statement: import "gocalc/operations": cannot find package
Finally, when I try go build . from the project dir, it chokes similar to the previous paragraph: import "gocalc/calcfns": cannot find package
How should I structure my child packages and/or import statements in such a way that go build won't fail?
Stupidly, I forgot to export my GOPATH variable, so go env displayed "" for GOPATH. (thanks to jnml for suggesting to print go env; +1).
After doing this (and moving the main program to its own folder {project-dir}/gocalc/gocalc.go), I could build/install the program via go install gocalc/gocalc.
Moral of the story, make sure you type export GOPATH=... instead of just GOPATH=... when setting your $GOPATH environment variable
Please try to also add output of $ go env to provide more clues. Otherwise both the directories structure and (the shown) import statements looks OK.
However the sentence
When I try to go build operations (from the project dir), I get the response: can't load package: package operations: import "operations": cannot find package
sounds strange. It seems to suggest you have
package operations
import "operations"
in 'operations.go', which would be the culprit then...?
Very easy:
Lets say I have a project/app named: golang-playground
Put your root dir under GOPATH/src/, in my case GOPATH=~/go/src (run command go env to get your GOPATH). so complete path for my app is ~/go/src/golang-playground
Lets say you want to use function Index() inside of file: router.go from my main.go file (which of course is on root dir). so in main.go:
import (
...
"golang-playground/router"
)
func main() {
foo.Bar("/", router.Index) // Notice caps means its public outside of file
}

Resources