Import vars/consts from main in subpackage - go

I have a Go project at $GOPATH/dalu/myproject with the following files :
main.go:
package main
import "dalu/myproject/subpackage"
var GV string = "World"
func main() {
subpackage.Hello()
}
subpackage/subpackage.go:
package subpackage
import (
"fmt"
"dalu/myproject"
)
func Hello() {
//? fmt.Println("Hello"+GV)
}
Bonus (if I could):
I tried something similar with more subpackages and when trying to import a subpackage in main that imports another subpackage which imports the first mentioned subpackage I get "import cycle not allowed"

As the compiler so nicely said, Go doesn't allow cyclic dependencies, and unlike C++ there are no forward declarations tricks to be done here.
if you have a state where:
A imports B AND B imports A
it measns you need to move whatever they share between them to package C, and do:
A imports B, C AND B imports C
and everyone's happy!
or in your example, add a file called dalu/myproject/gv/gv.go and in it define this GV. Then import it in both main and subpackage

Related

access main struct from packages

Please consider this sample go code, also here: https://play.golang.org/p/ZcNy_crAg51
package main
import (
"fmt"
"play.ground/foo"
)
type SampleStruct struct {
token int
}
var (
MainSampleVar = SampleStruct{token: 333}
)
func main() {
fmt.Println("Hello!")
b := foo.Auxstruct{AuxToken: 4333}
fmt.Printf("b: %#v\n", b)
foo.AuxHello()
}
-- go.mod --
module play.ground
-- foo/foo.go --
package foo
import "fmt"
type Auxstruct struct {
AuxToken int
}
func AuxHello() {
fmt.Println("Aux says hello!")
}
I am able to access foo.Auxstruct in main.go.
Is it possible to go the other direction and access main.SampleStruct in package foo?
Please show how / explain.
This is not possible in Go because it would result in a circular dependency: play.ground imports play.ground/foo and play.ground/foo imports play.ground. Go doesn't allow such circular dependencies because they have many disadvantages.
There are several possible solutions:
You could move SampleStruct into the play.ground/foo package. This way you can use SampleStruct in play.ground/foo and import it into play.ground.
Alternatively, move SampleStruct into its own package, for example play.ground/bar. This way you can import play.ground/bar into both play.ground/foo and play.ground.

cgo doesn't export functions in imported packages

I'm trying to build existed Go package into C shared library and header using CGO.
I built the package with -buildmode c-shared as documented.
-buildmode=c-shared
Build the listed main package, plus all packages it imports,
into a C shared library. The only callable symbols will
be those functions exported using a cgo //export comment.
Requires exactly one main package to be listed
And used //export Func to expose functions as C symbols.
All //export functions in main package are exported properly. However when I moved those functions to sub-package (with //export), those functions are not exported. I imported the sub-package in main package, too.
Here's my code.
main.go
package main
import "C"
import (
"fmt"
_ "github.com/onosolutions/archanan-cgo/c"
"math/rand"
)
// FuncInMain generates a random integer.
//export FuncInMain
func FuncInMain(max C.int) C.int {
return C.int(rand.Intn(int(max)))
}
func main() {
fmt.Printf("Hello World %d!\n", int(FuncInMain(256)))
}
c/c.go
package c
import "C"
import (
"math/rand"
)
// FuncInSubPackage generates a random integer.
//export FuncInSubPackage
func FuncInSubPackage(max C.int) C.int {
return C.int(rand.Intn(int(max)))
}
Then only FuncInMain is exported.
I read through CGO documentation, but there's nothing saying about exporting in sub-packages. The only clue I got is through go help buildmode, but it said that all imported sub-packages will be compiled. I'm not sure whether it isn't supported or I missed some configurations.
I'd love to achieve that to be able to modularize //export functions.
Both of them have own C.type, so as far as I know, there's no way to import function with C.type but using linking.
I didn't tried, but give it a chance:
import _ "unsafe"
//go:linkname FuncInSubPackage c.FuncInSubPackage
//export FuncInSubPackage
func FuncInSubPackage(max C.int) C.int

Golang local import

I am attempting to do a local import but it fails.
My environment is:
echo $GOPATH
/home/peter/go
echo $GOROOT
/usr/local/go
The entry point is:
/home/peter/go/src/projects/pkgs1/main.go
The imported file is:
/home/peter/go/src/projects/pkgs2/stuff.go
main.go
package main
import (
"fmt"
"projects/pkgs2" // <- this does not resolve
)
func main(){
fmt.Println("123")
pkgs2.X()
}
stuff.go
package pkgs2
import "fmt"
func X(){
fmt.Println("X")
}
Any pointers on what I do wrong?
Your import path is correct and should resolve successfully, but as written, your program won't compile because the import isn't being used and there is no local function named x.
As mentioned by mkopriva your x function in pkgs2 isn't exported and you have not qualified it when trying to use it in your main package.
To export a function, it needs to start with a capital letter.
To use the function in another package, you need to prefix the package name to the function name.
main.go
package main
import (
"fmt"
"projects/pkgs2"
)
func main(){
fmt.Println("123")
pkgs2.X()
}
stuff.go
package pkgs2
import "fmt"
func X(){
fmt.Println("X")
}

How to import main folder from another folder [duplicate]

This question already has answers here:
Access main package from other package
(2 answers)
Closed 3 years ago.
app/main.go
package main
import (
"fmt"
)
var varInMain string
func exm() {
varInMain = "Hello, playground"
fmt.Println(varInMain)
}
app/folder/call.go
package folder
import (
"fmt"
Main "../" -> ERR// or "app" -> ERR
)
func main() {
fmt.Println(Main.varInMain)
}
I can not call main.go variable or func. from folder/call.go.
How can i do it? //And thats must be local package
If you want to share vars across packages then create a separate package where you declare exported variables by the first character in caps.
app/mypack/vars.go
package mypack
var MyVar string
then import in main and other packages like
package main
import (
"fmt"
mypack "app/mypack"
)
func main(){
mypack.MyVar = "Hello, playground"
}
same way import in app/folder/call.go and use
Main means that this package uses everything in your project(if not just remove it from your project and everything will be ok). And so you cannot import main because of cycle import. So you should create separate package and use it in main and in other packages if you want.

import code from a separate package/folder [duplicate]

This question already has an answer here:
Imported struct from other package is undefined
(1 answer)
Closed 4 years ago.
I have this directory layout:
/baba
biz.go # package baba
/hello
foo.go # package main
biz.go looks like this:
package baba
func Foodd(z int) int {
return z + 5
}
and foo.go looks like this:
package main
import (
"fmt"
"log"
)
func main() {
log.Fatal(Foodd(3))
}
currently this doesn't compile because Foodd is not recognized. How do I import the baba package in foo.go?
I assume if I compile like so, that it will pull in the right files:
go build foo.go
Or do I need to include the files in the baba package in the go build command? (I would hope not).
You need to import the baba package in order to use it from your main package. That will look something like:
package main
import (
"fmt"
"log"
"github.com/the1mills/myproject/baba"
)
func main() {
log.Fatal(baba.Foodd(3))
}
Imported packages are referred to by their package name, which is usually, but not always, the last element of the import path.
Usually, people let goimports handle finding the correct import path and automatically adding it. Your editor of choice probably has goimports integration.
Also see this answer for some other references and how to set up your directory structure.

Resources