74

How do I access a variable that was declared/init in my main.go in a different .go package/file? Keeps telling me that the variable is undefined (I know that global variables are bad but this is just to be used as a timestamp)

in main.go

var StartTime = time.Now()
func main(){...}

trying to access StartTime in a different .go file but keep getting StartTime undefined

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Nighthee
  • 1,329
  • 3
  • 13
  • 14
  • 2
    Possible duplicate of [go build works fine but go run fails](http://stackoverflow.com/questions/21293000/go-build-works-fine-but-go-run-fails) – Ainar-G Jan 27 '16 at 13:42
  • Is the first letter on the variable name capitalized? – olif Jan 27 '16 at 13:43
  • Yes, it is capitalized, and my go build fails – Nighthee Jan 27 '16 at 13:44
  • are you including all relevant files when running the program? That is, when running the code, are you running go run file1.go file2.go ..etc – olif Jan 27 '16 at 13:45
  • Yes, to be more concise, I have a variable called 'var StartTime = time.Now()' in my main.go But when i try to access StartTime in a different .go of the same directory, it says its undefined, would i have to include "main" in the .go file that im trying to call? – Nighthee Jan 27 '16 at 13:47
  • 1
    Hmm, perhaps it would be better to "inject" the variable into the other package, for instance, couldn't you set the variable in the other package in the main method of your main package? If you pass it by reference, then the variable is still shared... – olif Jan 27 '16 at 13:50
  • Unfortunately I can't do that, cause of the way our overall system is built. I assumed if it was global, all files would have access to it but i guess go doesn't let you do that – Nighthee Jan 27 '16 at 13:52
  • I'm afraid you will have a circular reference otherwise. Your main.go package is dependent on the "otherPackage", and now you want to make the "otherPackage" dependent on the main package.. – olif Jan 27 '16 at 13:54
  • Okay, I've made that change so now main is in my src directory and then theres a directory in src called timeStamp with the other .go file in it, but it still gives me the same StartTime undefined – Nighthee Jan 27 '16 at 14:00
  • 1
    @Nighthee: yes, because you're not importing `main` into the other package, so it doesn't exists there (both because you can't have a circular dependency, and because you can't import a `main` package.) – JimB Jan 27 '16 at 14:01

3 Answers3

110

I would "inject" the starttime variable instead, otherwise you have a circular dependency between the packages.

main.go

var StartTime = time.Now()
func main() {
   otherPackage.StartTime = StartTime
}

otherpackage.go

var StartTime time.Time
olif
  • 3,221
  • 2
  • 25
  • 23
  • 2
    aren't you re-declaring the variable? – Kulbhushan Singh Dec 16 '19 at 12:55
  • 1
    I think it would be nicer in terms of memory usage and not double declaring variables, if you declared all but one of the variables as pointers and do an address assignment injection. – Can Kavaklıoğlu Jul 26 '21 at 23:26
  • @Sing: He is not re-declaring the variable. Each package has its own declaration. They are different variables. The first declaration in package `main` is required to fetch the timestamp at the very beginning. Then it is copied into `otherpackage` later on. @Can: Space is lost, when using non-optimal algorithms, for example when multidimensional arrays are produced, where a temporary row would be enough. Handling a single timestamp by pointers gains nothing relevant. Is the pointer even shorter than the value of the timestamp? – Blcknx Apr 07 '23 at 10:50
18

I create a file dif.go that contains your code:

package dif

import (
    "time"
)

var StartTime = time.Now()

Outside the folder I create my main.go, it is ok!

package main

import (
    dif "./dif"
    "fmt"
)

func main() {
    fmt.Println(dif.StartTime)
}

Outputs:

2016-01-27 21:56:47.729019925 +0800 CST

Files directory structure:

folder
  main.go
  dif
    dif.go

It works!

frogatto
  • 28,539
  • 11
  • 83
  • 129
joy miao
  • 299
  • 1
  • 4
  • My 'dif' is a restful API and won't be called when the program starts but only when its invoked through URL, so i need to put the StartTime in main.go and pass it to dif, you're passing it from dif to main, thanks for the try though! – Nighthee Jan 27 '16 at 14:05
  • A better way is to use function, instead of a variable, just make it a function that whenever its called you get a timestamp. – ROOT Aug 14 '19 at 07:16
0

I suggest use the common way of import.

First I will explain the way it called "relative import" maybe this way cause of some error

Second I will explain the common way of import.

FIRST:

In go version >= 1.12 there is some new tips about import file and somethings changed.

1- You should put your file in another folder for example I create a file in "model" folder and the file's name is "example.go"

2- You have to use uppercase when you want to import a file!

3- Use Uppercase for variables, structures and functions that you want to import in another files

Notice: There is no way to import the main.go in another file.

file directory is:

root
|_____main.go
|_____model
          |_____example.go

this is a example.go:

package model

import (
    "time"
)

var StartTime = time.Now()

and this is main.go you should use uppercase when you want to import a file. "Mod" started with uppercase

package main

import (
    Mod "./model"
    "fmt"
)

func main() {
    fmt.Println(Mod.StartTime)
}

NOTE!!!

NOTE: I don't recommend this this type of import!

SECOND:

(normal import)

the better way import file is:

your structure should be like this:

root
|_____github.com
         |_________Your-account-name-in-github
         |                |__________Your-project-name
         |                                |________main.go
         |                                |________handlers
         |                                |________models
         |               
         |_________gorilla
                         |__________sessions

and this is a example:

package main

import (
    "github.com/gorilla/sessions"
)

func main(){
     //you can use sessions here
}

so you can import "github.com/gorilla/sessions" in every where that you want...just import it.