5

I'm pretty new on Go but I'm from the C++ school. I just want to make a project and split the logic into multiple files.

In C++ I just need to put on my main_file.cpp a single

#include "my_own_lib.hpp" 

(similar to module.exports and then require('relative/path/to/my-own-lib') in Node.js)

and that's it. In Go I followed the same logic but my result is:

$ go run main.go
main.go:4:8: open /Users/mt/Documents/Codes/go/src/github.com/mt/Apollo/tst: no such file or directory

My files:

main.go

package main

import "fmt"
import "./tst"

func main() {
    fmt.Println("just testing")
    tst.p()
}

tst.go

package tst

import "fmt"

func p() {
    fmt.Println("ola")
}

Of course my file structure is:

myFolder/
   |- main.go
   |_ tst.go

Could someone tell me what is the right way to do this?

gavv
  • 4,649
  • 1
  • 23
  • 40
Chelo Tavano
  • 63
  • 1
  • 1
  • 5
  • 4
    Make sure to read about how packages work in go. Eg: golang.org/doc/code.html. Packages always are in a folder with the name of the package. In your example, tst.go should be inside a folder called tst – Riscie Jan 23 '16 at 19:22
  • 1
    also, when using "go run" you must specify all files you want to compile and run. Includes only finds packages in your gopath. In this case, you probably want to do "go run *.go" to actually run those two files. You only import stuff in a different "package", which also would be in a different directory than your "package main" code – David Budworth Jan 23 '16 at 19:23
  • Possible duplicate of [How to use custom packages in golang?](http://stackoverflow.com/questions/15049903/how-to-use-custom-packages-in-golang) – gavv Aug 03 '16 at 18:52

2 Answers2

5

If you set the package of tst.go to "package main" as well, you will be able to access p() without any import statements.

$ cat main.go 
package main

func main() {
    p()
}
$ cat tst.go 
package main

import "fmt"

func p() {
    fmt.Println("ola")
}
$ go build ./ && ./test 
ola

I believe this will suit your request:

I just want to make a project and split the logic into many different files.

If you're building a program and not a library, the accepted Go convention is to have all your files as "package main":

The package “main” tells the Go compiler that the package should compile as an executable program instead of a shared library. http://thenewstack.io/understanding-golang-packages/

Here's some examples of well-known idiomatic Go projects which do exactly as I say:

These are executables with the code split among multiple Go files, all of which belong to "package main".

Seeing as the OP is slightly unclear, you could choose to interpret that he wants to create an external package, tst. But he's clear when he says:

I just want to make a project and split the logic into many different files.

He says many files - not many external packages. And he also says:

of course my file structure is:

myFolder/
   |- main.go
   |_ tst.go

My suggestion is the correct way to do things in this case:

executable/
   |- main.go (package main)
   |- a.go (package main)
   |- b.go (package main)

With the application split among main, a and b.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Sevag
  • 191
  • 2
  • 15
  • sure, i'm trying to do this to build an API-REST with gin (https://gin-gonic.github.io/gin/) and follow the pattern defined by express(node js) users. routes on `routes`folder, controllers on `controllers`folder and so on. – Chelo Tavano Jan 24 '16 at 01:04
  • by the other hand, I've made 'go run *.go' and the output was expected but the main idea is just run my main file `main.go` or in gin framework my `app.js` – Chelo Tavano Jan 24 '16 at 01:09
  • Try changing the package of tst.go to "package main", then do "go build ./" to create an executable and run that executable. – Sevag Jan 24 '16 at 01:17
  • external packages are not "package main", they have their own package name. Main is reserved for the executable. – Snowman Jan 24 '16 at 02:20
  • Yes. But he's not trying to make an external package. He's trying to make a project, split across multiple files. – Sevag Jan 24 '16 at 12:50
  • I undestood the idea to call all my file as package main (and i have done it). but I still cannot get the expected output runing **only** my `main.go` file with `go run main.go`, otherwise when i run `go run *.go` command the output was the expected one – Chelo Tavano Jan 24 '16 at 22:08
2

If I read the question correctly:

The import path should be the full path, following the $GOPATH, so likely 'github.com/mt/Apollo/tst'

This is where the package code should reside and would also be the package import path. See this from the documentation:

The packages from the standard library are given short paths such as "fmt" and "net/http". For your own packages, you must choose a base path that is unlikely to collide with future additions to the standard library or other external libraries.

If you keep your code in a source repository somewhere, then you should use the root of that source repository as your base path. For instance, if you have a GitHub account at github.com/user, that should be your base path.

I have it working. Here is exactly what I've done:

main.go

package main

import (
    "fmt"
    "github.com/mt/Apollo/tst"
)

func main() {
    fmt.Println("just testing")
    tst.P()
}

tst.go

package tst

import (
    "fmt"
)

func P() {
    fmt.Println("ola")
}

directory structure looks like:

mt/Apollo/main.go

mt/Apollo/tst/tst.go

The other thing to note is that I capitalized the "P" in func p(). Lower case identifiers are not exported. More on that here

Snowman
  • 3,170
  • 1
  • 18
  • 28
  • I've followed your hint but the output wasn't the expected one :/ – Chelo Tavano Jan 24 '16 at 01:10
  • Does `/Users/mt/Documents/Codes/go/src/github.com/mt/Apollo/tst`exist? – Snowman Jan 24 '16 at 02:15
  • of course that rout exist, `Apollo` is my project folder and tst is a `.go`file – Chelo Tavano Jan 24 '16 at 22:02
  • @Chelo Tavano Check out [golang.org/doc/code.html#Workspaces](https://golang.org/doc/code.html#Workspaces) and [golang.org/doc/code.html#PackagePaths](https://golang.org/doc/code.html#PackagePaths). Your package source code should be in a directory with the package name, your import path would then include the full directory path. – Snowman Jan 25 '16 at 22:26
  • @CheloTavano see the edit in my answer and see if that helps – Snowman Jan 25 '16 at 23:00