How to pass anonymous struct as function argument - go

The problem is that I can't access struct properties inside Converter function, but I can print em.
func main() {
var io struct {
Src string
Dest string
}
flag.StringVar(&io.Src, "src", "temp_dir", "")
flag.StringVar(&io.Dest, "dest", "users_dir", "")
modules.Converter(&io)
}
// ./src/modules/converter.go
package modules
func Converter(io interface{}) {
fmt.Println(io)
// => {temp_dir users_dir}
}
What am I doing wrong?
What is the right way to pass multiple props into function?

first, you need to change the io struct to Io
var Io struct {
Src string
Dest string
}
And the function input should change this way
package modules
import "fmt"
func Converter(io *namePackage.Io) {
fmt.Println(io.Src,io.Dest)
}

Related

How to ensure read-only variables and maps in golang

I want my programs have access to global read-only regex and maps. Here's what i thought of :
var myRegex *regexp.Regexp
var myMap map[string]string
func init() {
myRegex = regexp.MustCompile("blah")
myMap = map[string]string{"blah": "blah"}
}
or i can do
type myStruct struct {
// already have bunch of other struct fields
myRegex *regexp.Regexp
myMap map[string]string
}
func Initialize() *myStruct {
m := myStruct {
// bunch of other stuff
myRegex: regexp.MustCompile("blah")
myMap: map[string]string{"blah": "blah"}
}
But how i can ensure that these variables won't be writable by any other piece of my software ?
As long as you're dealing with pointers ( maps are pointers anyway ), you' ll never be able to ensure that your map or regex is ReadOnly.
( Ok, unless you copy the value with the function each time and return a new pointer... But i'm not sure that's what you want to achieve :)
If i take your example, and add a simple main code :
package main
import (
"fmt"
"regexp"
)
var myRegex *regexp.Regexp = regexp.MustCompile("blah")
var myMap map[string]string
func init() {
myRegex = regexp.MustCompile("blah")
myMap = map[string]string{"blah": "blah"}
}
type myStruct struct {
// already have bunch of other struct fields
myRegex *regexp.Regexp
myMap map[string]string
}
func Initialize() myStruct {
return myStruct{
// bunch of other stuff
myRegex: regexp.MustCompile("blah"),
myMap: map[string]string{"blah": "blah"},
}
}
func getMap() map[string]string {
return myMap
}
func main() {
fmt.Println(myMap)
myMap["blah2"] = "blah2"
fmt.Println(myMap)
fmt.Println(getMap())
m := Initialize()
fmt.Println(m.myMap)
m.myMap["test"] = "test"
fmt.Println(m.myMap)
}
you see that i can modify the maps:
❯ ./main
map[blah:blah]
map[blah:blah blah2:blah2]
map[blah:blah blah2:blah2]
map[blah:blah]
map[blah:blah test:test]
Regex would be exactly the same.
If you really want to ensure that your regex and maps will never be updated by mistake by another piece of code, there's couple of solutions; most of them consisting of moving your read-only variables in there own package and never give direct access to them. Something like this for instance
package mapreadonly
type ReadOnlyMap struct {
m map[string]string
}
func (elem ReadOnlyMap) Get(key string) (string, bool) {
value, ok := elem.m[key]
return value, ok
}
var Map1 ReadOnlyMap = ReadOnlyMap{
m: map[string]string{
"blah": "blah",
},
}
and then import this package in your other files that requires it.
But as said, your question is lacking a bit of context to ensure that the answer is what your expect.

Golang http handler testing with inner functions

I want to build a testing part for my http handlers, and I want to use the http handler functions how they are, but I want to have separate functions that mock the db part of the handling. What I have in mind is something like:
package main
import (
"log"
"testing"
)
// DB functions
type UserDBFunctions interface {
InsertUser() string
}
type UserDB struct {
}
func (u UserDB) InsertUser() string {
return "hello"
}
// http handler functions
type UserHandlerFunctions interface {
Register() string
}
type UserHandler struct {
userDb *UserDB
}
func newUserHandler() UserHandler {
return UserHandler{userDb: new(UserDB)}
}
func (u UserHandler) Register() string {
str := u.userDb.InsertUser()
return str + " world"
}
func main() {
var i UserHandlerFunctions = newUserHandler()
str := i.Register()
log.Println(str)
}
// test functions
type FakeUserDBFunctions interface {
InsertUser() string
}
type FakeUserDB struct {
}
func (u FakeUserDB) InsertUser() string {
return "bye"
}
func newFakeUserHandler() UserHandler {
return UserHandler{userDb: *UserDB(&FakeUserDB{})}
}
func TestRegisterUser(t *testing.T) {
t.Run("register user", func(t *testing.T) {
var i UserHandlerFunctions = newFakeUserHandler()
str := i.Register()
log.Println(str)
})
}
So the first interface is for the real db functions, then there is the http handler which calls the db function and below the main() function there should be the tests with a mockup of the db function. But this part doesn't work. How do I replace the real interface in the newUserHandler by a mockup.
I would really appreciate help. 😊
The UseHandler shall use UserDBFunctions instead of UserDB.
type UserHandler struct {
userDb UserDBFunctions
}
Here is the modified one https://play.golang.org/p/nLiaomKA2NH

Change value of pointered argument inside a function

I'm stuck on something that seems/should be easy in Go.
I wrote a small go playground to explain my problem more easily => https://play.golang.org/p/Sm0SzrvEZS_o
package main
import (
"github.com/sirupsen/logrus"
)
type toto struct {
name string
}
func transform (data ...interface{}) {
logrus.Info("data before ", data)
data[0] = "tutu"
logrus.Info("data after ", data)
}
func main() {
var titi toto
logrus.Info("titi before ", titi) // -> empty
transform(&titi)
logrus.Info("titi after ", titi) // -> should have a name but don't
}
The goal is to pass a struct to a function, modifying in it and continue to use it in the caller function. Sadly, the argument is modified inside the child function but don't move into the caller.
I'm a beginner in this language, maybe I just missed something somewhere... Many thanks in advance for your help
This seems to do it:
package main
type toto struct { name string }
func transform (data ...interface{}) {
t := data[0].(*toto)
t.name = "tutu"
}
func main() {
var titi toto
transform(&titi)
println(titi.name == "tutu")
}
Sounds like you want a pointer.
In your example you use an array of interface{}, is there a particular reason for this? In general you should be explicit with your types in Go, especially since you're dealing with a simple struct.
package main
import (
"log"
)
type toto struct {
Name string
}
// to help with printing
func (t *toto) String() string {
return t.Name
}
// transform takes an array of pointers to the toto struct
func transform(totos ...*toto) {
log.Printf("totos before: %v", totos)
// unsafe array access!
totos[0].Name = "tutu"
log.Printf("totos after: %v", totos)
}
func main() {
// variables in Go are usually defined like this
titi := toto{}
transform(&titi)
}
In Go, the variable that's passed as a parameter in a function is actually a copy of the variable, not the actual variable itself. If you want to modify the variable that's passed, you need to pass it in as a pointer.
Personally, whenever I create a function that accepts a struct, I set the function to accept a pointer to an instance of that struct. This has the benefits of being more memory efficient (since my program doesn't have to create copies of the variable every time the function is called) and it allows me to modify the instance of the struct that I pass.
This is how I would do it:
package main
import (
"github.com/sirupsen/logrus"
)
type toto struct {
name string
}
func transform (t *toto) {
logrus.Info("t before: ", t)
// since t is a pointer to a toto struct,
// I can directly assign "tutu" to the "name" field
// using the "dot" operator
t.name = "tutu"
logrus.Info("t after: ", t)
}
func main() {
// init a pointer to a toto instance
titi := &toto{}
logrus.Info("titi before: ", titi) // -> empty
// this works because transform() accepts a pointer
// to a toto struct and and titi is a pointer to a toto instance
transform(titi)
logrus.Info("titi after (as a pointer): ", titi) // -> not empty
logrus.Info("titi after (as a value): ", *titi) // -> also not empty
}

get name from struct passed to function

How to get the name of an struct/interface?
pkg
package crud
type User struct {
ID uint
Name string
Email string
}
main
package main
import "./crud"
func get_struct(value interface{}){
// print "User"
}
func main(){
get_struct(&crud.User{})
}
The reflect package provides this; you simply create a new reflect.Value from the variable and inspect its type:
func get_struct(value interface{}){
var name string
ref := reflect.ValueOf(value)
if ref.IsValid() {
name = ref.Type().Name()
} else {
name = "nil"
}
fmt.Println(name)
}
Note: you may not get the output you want if a pointer is passed. You may want to consider using Type.String() over Type.Name().
Playground

Private fields and methods for a struct

In the following test code I would like to have both mytype and the doPrivate method private, so that only members of mytype can access it, but not other types\functions in the scope of the mypackage package.
Can I do this in golang?
package mypackage
type mytype struct {
size string
hash uint32
}
func (r *mytype) doPrivate() string {
return r.size
}
func (r *mytype) Do() string {
return doPrivate("dsdsd")
}
Fields size and hash as well as the doPrivate method should be encapsulated and no other type should have access to them.
In Go, an identifier that starts with a capital letter is exported from the package, and can be accessed by anyone outside the package that declares it.
If an identifier starts with a lower case letter, it can only be accessed from within the package.
If you need members in a type to only be accessed by members of that type, you then need to place that type and its member functions in a separate package, as the only type in that package.
That's not how "privacy" works in Go: the granularity of privacy is the package.
If you really want only the members of mytype to access some fields, then you must isolate the struct and the functions in their own package.
But that's not the usual practice. Whether Go is OOP or not is debatable but clearly the practice isn't to encapsulate the code by a struct like you seem to want to do. Usually a package is small enough to be coherent: if you don't want to access fields from within the package, don't access them.
You can create an interface with the method you wish to expose and only access the object when wrapped into that interface.
package main
type mytype struct {
size string
hash uint32
}
// interface for exposed methods
type myinterface interface {
do() string
}
// constructor (optional)
func newMytype(size string, hash uint32) myinterface {
return &mytype{size, hash}
}
func (r *mytype) doPrivate() string {
return r.size
}
func (r *mytype) do() string {
return r.doPrivate()
}
func main() {
// with constructor
t := newMytype("100", 100)
t.do()
// t.doPrivate() // t.doPrivate undefined (type myinterface has no field or method doPrivate)
// without constructor
t2:= myinterface(&mytype{"100", 100})
t2.do()
// t.doPrivate() // t.doPrivate undefined (type myinterface has no field or method doPrivate)doPrivate)
}
https://play.golang.org/p/awjIIj8Kwms
You cannot do this in Go. Visibility is on a per package level only. But you may split your package into two.
In one module there can be any number of packages.
Public/Private works only across one package.
All public fields, methods and functions starts with uppercase char.
All private fields, methods and functions starts with lowercase char.
To add package to your module or program just create a lowercase folder and add package name to all files inside. Here is the example.
./main.go
./foo/foo.go
./foo/MyStruct.go
file ./foo/foo.go:
package foo
import "fmt"
func SomePublicFuncInFoo() {
somePrivateFuncInFoo()
}
func somePrivateFuncInFoo() {
fmt.Println("somePrivateFuncInFoo call")
}
file ./foo/MyStruct.go:
package foo
import "fmt"
type MyStruct struct {
MyPublicField string // starts with uppercase char
myPrivateField string // starts with lowercase char
}
func NewMyStruct(publicField string, privateField string) *MyStruct {
return &MyStruct{
MyPublicField: publicField,
myPrivateField: privateField,
}
}
func (self *MyStruct) SomePublicMethod() {
self.privateMethod()
}
func (self *MyStruct) privateMethod() {
fmt.Println("MyStruct", self.MyPublicField, self.myPrivateField)
}
file ./main.go:
package main
import (
"fmt"
"{your-module-name}/foo" // this line should be added by your IDE
)
func main() {
foo.SomePublicFuncInFoo()
myStruct := foo.NewMyStruct("string1", "string2")
fmt.Println("myStruct.MyPublicField=", myStruct.MyPublicField)
myStruct.SomePublicMethod()
}
You can have private variables and functions in Go, but the trick is that you simply don't define them in the struct. Bind them to the call stack of a closure, and simply don't return them.
package main
import (
"fmt"
)
type mytype struct {
Do func() string
}
func MyType(size string, hash uint32) mytype {
doPrivate := func() string {
return size
}
return mytype{
Do: func() string {
return doPrivate()
},
}
}
func main() {
instance := MyType("100", 100)
fmt.Println(instance.Do())
}

Resources