Go’s Structs
specs
- Small example of struct emebeds, tags , etc…
// - async.go -
package main
import (
"fmt"
"sync"
)
// ----------------
// This is simple "inheritance" via embeding, but beware of such implementations.
// It exposes public methods of embeded structs, as sideeffect.
// ----------------
type AsyncStruct struct {
sync.Once
sync.Mutex
sync.WaitGroup
value int
}
func (a *AsyncStruct) Increase() {
a.Add(1)
go func() {
a.Lock()
defer a.Unlock()
defer a.Done()
a.value++
}()
}
func main() {
a := AsyncStruct{}
a.Increase()
a.Wait()
fmt.Print(a.value)
}
// - logger.go -
package main
import (
"fmt"
"os"
"github.com/sirupsen/logrus"
"go.uber.org/zap"
)
// ------
// Dependency injection using structs with interface fields.
// ------
type Logger interface {
Panic(args ...interface{})
Panicf(format string, args ...interface{})
Info(args ...interface{})
Infof(format string, args ...interface{})
Print(args ...interface{})
Printf(format string, args ...interface{})
Warn(args ...interface{})
Warnf(format string, args ...interface{})
Error(args ...interface{})
Errorf(format string, args ...interface{})
}
type Log struct {
Logger
}
type ZapFacade struct {
*zap.SugaredLogger
}
func (z *ZapFacade) Print(args ...interface{}) { z.Info(args) }
func (z *ZapFacade) Printf(format string, args ...interface{}) { z.Infof(format, args) }
func main() {
fmt.Println("Logrus (default)")
// Default Logrus
{
log := Log{logrus.New()}
log.Info("hi")
log.Warn("hi")
log.Error("hi")
}
fmt.Println("Logrus (json)")
{
log := Log{&logrus.Logger{
Out: os.Stderr,
Formatter: new(logrus.JSONFormatter),
Hooks: make(logrus.LevelHooks),
Level: logrus.DebugLevel,
}}
log.Info("hi")
log.Warn("hi")
log.Error("hi")
}
fmt.Println("UberZap")
{
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
log := Log{&ZapFacade{logger.Sugar()}}
log.Info("hi")
log.Warn("hi")
log.Error("hi")
}
}
// - struct_tags.go -
package main
import (
"fmt"
"reflect"
)
// --------------------------------------------
// Some quick example of struct tags (tags).
// -------------------------------------------
func main() {
data := struct {
Variable1 string `json:"name,omitempty"`
Variable2 string `unformated strings are OK!`
}{
"dummy1",
"dummy2",
}
t := reflect.TypeOf(data)
for _, val := range []string{"Variable1", "Variable2", "Variable3"} {
if field, ok := t.FieldByName(val); ok {
fmt.Printf("\nField: .%s\n", val)
fmt.Printf("\tWhole tag : %q\n", field.Tag)
fmt.Printf("\tValue of 'json': %q\n", field.Tag.Get("json"))
} else {
fmt.Printf("\nNo Field: .%s\n", val)
}
}
}
// - skip_json_fileds.go -