MyInterface with MyImplementation in separate files of a library - go

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

Related

Can I reference an imported type without using dot notation

Consider the following interface definition:
package repos
import (
resources "unit/pkg/resources"
)
type IRepo interface {
fetch(int32) (resources.IResource, error)
update(resources.IResource) (resources.IResource, error)
new() resources.IResource
create(resources.IResource) (resources.IResource, error)
delete(int32) error
}
Is there a way to 'use' the imported package (in the sense of C++ namespaces), so that I don't need to explicitly name it using dot notation each time I reference one of its types (IResource)
(TBH - this may just mean that IResource belongs in the repos package and not in resources)
You can prefix the import declaration with the name . to import all of its identifiers:
package repos
import (
. "unit/pkg/resources"
)
However, import . is almost never the appropriate solution. If new identifiers are added to the resources package in the future, they can collide with existing identifiers in the repos package and break your build.
Furthermore, the fact that the package name is redundant with the type name may indicate that either the package or the types within that package should have a better name (see the Package names blog post for much more detail).
In this case, perhaps the abstraction boundary between resources and repos is doing more harm than good. What kind of resources are you dealing with here? Could the Resource type be moved into some higher-level package?
Finally, I would note that the IRepo interface seems very large and likely out-of-place. Go interfaces — unlike, say, Java interfaces — generally belong with the API that consumes the interface, not the API that provides implementations of that interface.
For more on that principle, see:
https://golang.org/wiki/CodeReviewComments#interfaces
https://hyeomans.com/golang-and-interfaces-misuse/
https://dave.cheney.net/2016/08/20/solid-go-design
https://dave.cheney.net/practical-go/presentations/gophercon-israel.html#_prefer_single_method_interfaces
You can use a type alias.
type IRes = resources.IResource
In contrast to a type definition, an alias is just another name for the same type and not a new distinct type. A type definition would be without the =.

Getting list of exported functions from a package in golang

Let's say I have some package
// ./somepkg/someFile.go
package somepkg
import "fmt"
func AnExportedFunc(someArg string) {
fmt.Println("Hello world!")
fmt.Println(someArg)
)
and I import it from my main go file
// ./main.go
package main
import (
"./somepkg" // Let's just pretend I have the full path written out
"fmt"
)
func main() {
fmt.Println("I want to get a list of exported funcs from package 'somefolder'")
}
Is there a way to get access to the exported functions from package 'somepkg' and then to consequently call them? Argument numbers/types would be consistent across all functions in somepkg. I've looked through the reflection package but I'm not sure if I can get the list and call the functions without knowing any information other than package name. I may be missing something from the godocs however, so any advice is appreciated. What I'm trying to do is essentially have a system where people can drop in .go files as a sort of "plugin". These "plugins" will have a single exported function which the main program itself will call with a consistent number and types of args. Access to this codebase is restricted so there are no security concerns with arbitrary code execution by contributors.
Note: This is all compiled so there are no runtime restrictions
What I'm trying to do is something like this if written in python
# test.py
def abc():
print "I'm abc"
def cba():
print "I'm cba"
and
# foo.py
import test
flist = filter(lambda fname: fname[0] != "_", dir(test))
# Let's forget for a moment how eval() is terrible
for fname in flist:
eval("test."+fname+"()")
running foo.py returns
I'm abc
I'm cba
Is this possible in golang?
Edit:
I should note that I have already "accomplished" this with something very similar to http://mikespook.com/2012/07/function-call-by-name-in-golang/ but require that each additional "plugin" add its exported function to a package global map. While this "works", this feels hacky (as if this whole program isn't... lol;) and would prefer if I could do it without requiring any additional work from the plugin writers. Basically I want to make it as "drop and go" as possible.
As you might've guessed, it is difficult to achieve in Go, if not impossible, as Go is a compiled-language.
Traversing a package for exported functions can only get you the list of functions. A sample for this is: Playground. This is a AST (Abstract Syntax Tree) method which means calling the functions dynamically is not possible, or requires too much of workarounds. Parsing function name string as function type doesn't work here.
Alternatively, you can use try methods by binding the exported functions to some type.
type Task struct {}
func (Task) Process0()
func (Task) Process1(v int)
func (Task) Process2(v float64)
func (Task) Process3(v1 bool, v2 string)
This totally changes the way we operate as the 4 methods are now associated with a type Task and we can pass empty instance of Task to call the methods defined on it. This might look like just another workaround, but is very common in languages like Go. A sample for this in Playground which actually works as expected.
In both the examples, I've used multiple files in playground. If you are not familiar with this structure, just create your workspace in your local as following and copy the code under each file name from playground:
<Your project>
├── go.mod
├── main.go
└── task
└── task.go
References:
How to dynamically call all methods of a struct in Golang? [duplicate]
How to inspect function arguments and types [duplicate]
How do I list the public methods of a package in golang [duplicate]
Abstract Syntax Tree - Wiki
Functions vs Methods in Go
The easiest way to do this is to use the template library to parse your code and insert the new package name where appropriate.
Playground
You can use this by loading all of the finals where you call the user package and then output the generated file to the execution directory.

In Go, is it convention to capitalize type names?

In most Go programs I have seen, even those that have just one package, the names of types are written with a capital letter, which makes them exported.
Is this just a convention to make clear that they are types or is there a need for all types to be exported?
Initially I was going to put examples here of exported types, but looking around some popular Go projects I only found exported types so far. So any example of an unexported type in a reasonably large Go project would be welcome.
The type starting with an uppercase letter are exported to other packages. Those starting with a lowercase letter can be used only inside the package. Important note: it is possible to export an interface without exporting the struct that implements it.
It is not a convention to export types. Only export them if you allow them to be used outside the package. In the example you provided, there was no need to export the Server type, because it has no exported field or methods.
Export only the types that are part of the contract with the client. Exporting types that are only used internally is a mistake and is confusing in the documentation.
Edit:
A little clarification about the Server type. It implements the http.Handler interface (must define ServeHTTP(http.ResponseWriter, *http.Request) ), so it is possible to make it not exported and use the interface as the return type of NewServer function.
Types can be private.
Having a public function returning a private type however does not work. As long as the type is only used package internally, I keep it private.
EDIT:
In your example, Server has to be public because it is returned by public functions and thus used outside the package. The function NewServer returns *Server.
EDIT for new example:
In the new example this is the main package. It can't be imported anyway.
It's not a matter of convention, Go actually uses capitalization to determine which things are exported, i.e. available when you import the package.
E.g. if I have:
package a
const Exported = "hi"
const nonExported = "mom"
Then in a different package, you can import a.Exported but not a.nonExported:
package main
import "PATH/a"
func main() {
println(a.Exported)
// this won't compile
// println(a.nonExported)
}

Go: "instance" redeclared in this block

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 ;-)

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