Go’s Structs

#Tools

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 -