Go: "instance" redeclared in this block - go

I have these two files:
daoFactory.go
package dao
import "sync"
type daoFactory struct {}
var instance *daoFactory
//some functions
fakeProvisionDao.go
package dao
import (
"sync"
"model"
)
type provisionDao struct {
}
var instance *provisionDao
//some functions
Both are in the same package: dao.
I get this error:
"instance" redeclared in this block
Obviously, the cause is that instance variable is declared in both files. I'm beggining in Go programming and I don't know how should I handle with this error.

Files have no real meaning for go, unlike in java, python and many others, they are just for you to organize your code as you see fit.
In go variables are visible package wide, that means that both declartions of instance are variables with package wide visibility. Hence the compiler complains about having two global variables with the same name.
Rename any one of your two instance variables and it will compile.
Reading the links in the comments above is highly recommend ;-)

Related

How to access unexported package private variable

Code like below
package internal
var internalVar = "foobar"
How can i access this internalVar from another package like package main?
internal package is placed in a 3rd party library, and my application needs to use some private info which original author is not willing to expose as a public API.
As #mkopriva mentioned, internal variables should not be accessed outside their packages at all. Go explicitly does that as a way to enforce accessibility and if the internal var is not exported, then it shouldn't be accessed. Again: don't do this, it's bad Go and we don't like it. Always export your variables when you need to access them outside your packages.
That huge disclaimer above being said, there are ways on how you can access internal variables: pointers, assembly and linkname. I'll explain the later since it's the easiest one:
Go compiler has this nifty directive called //go:linkname. It basically links variables/functions between different packages. From the documentation:
//go:linkname localname [importpath.name]
This special directive does not apply to the Go code that follows it. Instead, the //go:linkname directive instructs the compiler to use “importpath.name” as the object file symbol name for the variable or function declared as “localname” in the source code. If the “importpath.name” argument is omitted, the directive uses the symbol's default object file symbol name and only has the effect of making the symbol accessible to other packages. Because this directive can subvert the type system and package modularity, it is only enabled in files that have imported "unsafe".
That means that you can use it to access otherwise unexported functions and variables, with something like this:
main.go
package main
import (
"temp/test-access-internal/internal"
_ "unsafe"
)
//go:linkname message temp/test-access-internal/internal.message
var message string
func main() {
message = "abc"
println(message)
internal.SayHello()
}
internal/internal.go
package internal
var message string = "Hello!"
func SayHello() {
println(message)
}
You will see that the output respects the "abc" value we've overwritten.
Don't do this unless you really, really needs to monkey patch something.

Is it possible to reuse constant names in different file scopes?

Is it possible to have two constants with the same name in different files?
foo.go
const {
deviceId = 1 // I dont need this outside the file scope
}
type DeviceA struct {
.. some fields..
// I cannot make constant fields here
}
.. some methods ...
bar.go
const {
deviceId = 2 // I dont need this outside the file scope
}
type DeviceB struct {
.. some fields ..
// I cannot make constant fields here
}
.. some methods ...
If I do this, I get that deviceId has been redeclared. How can I keep these constants in the scope of the file?
I would not mind using some kind of namespace for the constants if that were a solution to this.
The Go Programming Language Specification
Packages
Go programs are constructed by linking together packages. A package in
turn is constructed from one or more source files that together
declare constants, types, variables and functions belonging to the
package and which are accessible in all files of the same package.
Those elements may be exported and used in another package.
Source file organization
Each source file consists of a package clause defining the package to
which it belongs, followed by a possibly empty set of import
declarations that declare packages whose contents it wishes to use,
followed by a possibly empty set of declarations of functions, types,
variables, and constants.
[constants] belonging to the package are accessible in all files of the same package.
The fundamental Go compilation unit is the package. The source files in the package are merged to form the input to the compiler.
To answer your question: It is not possible to have two constants with the same name, in the same scope, the same package in separated files.
There is no namespace or file scope in Go.
However, it is possible to have two constants of the same name in the same package but declared at different scope:
package main
import (
"fmt"
)
const a = 1
func main() {
const a = 2
fmt.Println(a) // output is 2
}
For details of scope, please see: https://golang.org/ref/spec#Declarations_and_scope

MyInterface with MyImplementation in separate files of a library

The project structure requires to define interface and implementations in separate files.
It's best to download a small isolated test case to get a picture, but here's the code too. It's a library project that's why mylib is declared as package for each file. I wanted to have subpackages but golang doesn't allow that, so instead I put everything under one package while files are in separate directories.
Download Test Project
src/interfaces/my_interface.go
package mylib
type MyInterface interface {
foo()
bar()
}
src/interfaces/my_implementation.go how to import interface here?
package mylib
type MyImplementation struct {}
// possible to declare *MyInteface here?
func (imp *MyImplementation) foo() {}
func (imp *MyImplementation) bar() {}
test/implementations/implementation_test.go
package implementations
import (
"testing"
"fmt"
"implementations"
mylib2 "interfaces" // why mylib2 here?
)
func TestImplementation(t *testing.T) {
// how to declare variable of type `MyInterface` and assign an object `MyImplementation` to it
interface_type_var := mylib2.MyInterface() // error
interface_type_var := mylib.MyImplementation{} // error
fmt.Println("Test successful")
}
Question
How can I declare a type of MyInterface and assign object of MyImplementation to it.
how to import and interface in the implementation file
Autocomplete of IDE put this under imports automatically as I was importing interface type. not sure why. mylib2 "interfaces". i learned it's an alias but why do we need alias here?
Help fix the code in the implementation_test please
You have already declared a type of MyInterface inside src/interfaces/my_interface.go. You don't have to redeclare it and you don't have to explicitly assign MyImplementation to the interface. All you have to make sure is that your MyImplementation implements all the methods from the interface. As long as both files are in the same package and same folder level, your implementation automatically becomes your interface.
As long they are both in the same package and folder you do not have to import interface inside implementation
At time of this writing Gogland is in Early Access Program which is just another name for BETA :). I don't think SO allows commenting on anything in beta. Sorry.
EDIT
Based on the structure of your code, you are taking bit wrong approach when trying to use subfolders. If you are using subfolders, those subfolders should be independent packages. So let's say your GOPATH is ~/go. You need a structure like this: ~/go/src/github.com/user/mylib. So if you want a subfolder/subpackage you would have something like this ~/go/src/github.com/user/mylib/util and util would be its own package. It's wrong to try to have Implementations in one folder and interfaces in another. Rather group them logically and create subpackages. Then in your test you can use them like this:
import(
"github.com/user/mylib"
"github.com/user/mylib/util"
)
github.com or any other repo service is important specially if you are writing library that is suppose to be reusable in any project.
Besides that, I'd suggest to use more stable IDE or editor.
Hope this helps

How to define a struct globally and reuse it packages

Im very new to Go and have this "design" problem.
I have a main program passing jobs through channels. Each job will end up in a function defined in separate "worker" packages. Jobs are structs.
Now i want each function called, to return result as a common struct through a "result" channel. But the package doesnt know about the struct definition i have in main and so i cannot define it.
package main
type resultEvent struct {
name string
desc string
}
Then in a worker package:
package worker
func Test() {
result := &resultEvent{name: "test"}
}
Of course the idea is to eventually send this result down a channel, but even this simple example wont work, because worker doesnt know about resultEvent.
What would be the correct way of doing this?
Update:
It should be noted that there will be many worker packages, doing different things. Sorta like "plugins" (only not pluggable at all).
I dont want to define a redundant struct in each go-file and then have to maintain that over maybe 50 very different worker-packages.
Im looking for what would be the correct way to structure this, so i can reuse one struct for all worker-packages.
Basically, anything that lives in package main will only ever be able to be referenced from that pacakge. If you want it to be shared between multiple packages, put it in the worker package and export it (Upper case the first letter), then import worker from main.
No matter what, you will have to import the package which contains the type you'd like to use. However, the reason this isn't working for you is because your type is not exported. You need to uppercase the types name like;
type ResultEvent struct {
name string
desc string
}
Worth checking out what exported vs unexported means but basically upper case means exported which is similar to the public specifier in other systems languages. Lower case means unexported which is more like internal or private.
As pointed out in the comment and other answer you can't import main so I believe you'll have to move your types definition as well.
One possible way would be something like:
package workerlib
type ResultEvent struct {
Name string // Export the struct fields, unless you have a
Description string // real good reason not to.
}
Then stick the rest of the worker utility functions in that package. Unless you provide suitable methods to read the name and description from an event, simply export the fields. If you have an absolute need to make them changeable only from within the package they're defined in, you could keep them unexported, then provide a function to create a ResultEvent as well as methods to read the name and description.

What does an underscore in front of an import statement mean?

In this code from go-sqlite3:
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
"log"
"os"
)
what does the underscore in the import statement mean?
It's for importing a package solely for its side-effects.
From the Go Specification:
To import a package solely for its side-effects (initialization), use the blank identifier as explicit package name:
import _ "lib/math"
In sqlite3
In the case of go-sqlite3, the underscore import is used for the side-effect of registering the sqlite3 driver as a database driver in the init() function, without importing any other functions:
sql.Register("sqlite3", &SQLiteDriver{})
Once it's registered in this way, sqlite3 can be used with the standard library's sql interface in your code like in the example:
db, err := sql.Open("sqlite3", "./foo.db")
While other answers described it completely, for "Show me The Code" people, this basically means: create package-level variables and execute the init function of that package.
And (if any) the hierarchy of package-level variables & init functions of packages that, this package has imported.
The only side effect that a package can make, without being actually called, is by creating package-level variables (public or private) and inside it's init function.
Note: There is a trick to run a function before even init function. We can use package-level variables for this by initializing them using that function.
func theVeryFirstFunction() int {
log.Println("theVeryFirstFunction")
return 6
}
var (
Num = theVeryFirstFunction()
)
func init() { log.Println("init", Num) }
https://golang.org/doc/effective_go.html#blank
It's either a work in progress, or imported for side effects. In this case, I believe it's for the side effects, as described in the doc.
Let's say you have an Animal package. And your main file wants to use that Animal package to call a method called Speak but there are many different types of animals and each animal implemented their own common Talk method. So let's say you want to call a method Speak implemented in the Animal's package which internally calls Talk method implemented in each of the animal's package. So in this case you just want to do an import _ "dog" which will actually call the init method defined inside the dog package which actually registers a Talk method with the Animal package which it too imports.
As I'm new in Go, this definition made it more clear:
Underscore is a special character in Go which acts as null container. Since we are importing a package but not using it, Go compiler will complain about it. To avoid that, we are storing reference of that package into _ and Go compiler will simply ignore it.
Aliasing a package with an underscore which seems to do nothing is quite useful sometimes when you want to initialize a package but not use it.
Link

Resources