Our 16th Meetup at the 16th of February with a quick tour on Go 1.16 😊 . We will also have an outlook on the Go generics proposal.
Go 1.16 is expected to be released this Februrary! 🎉 🎆
From the preliminary release notes
⚠️ io/ioutilgets deprecated- package remains and will continue to work like before but new code should use functions from
ioandosinstead ioutilfunctions will become wrappers aroundioandos, exampleioutil.ReadFile
- package remains and will continue to work like before but new code should use functions from
⚠️ 32-bit iOS and macOS support is dropped- 🎉 Go adds support for the 64-bit macOS ARM architecture (aka Apple Silicon) with
GOOS=darwin, GOARCH=arm64crypto will be slower on this architecture since the optimized assembly code is still missingThere are arm64 assembly implementations: https://tip.golang.org/src/crypto/aes/cipher_asm.go and https://tip.golang.org/src/crypto/aes/asm_arm64.s
⚠️ GO111MODULE=onis now the default, i.e. go tools work in go modules mode by defaultgo buildandgo testdo not modify yourgo.mod, go.sumanymore- those two commands report if an module or checksum needs to be added or updated
- use
go getorgo mod tidyto do tha
- 🎉
runtime/metricsis a new package that provides a stable interface for accessing runtime metrics- generalizes
runtime.ReadMemStatsand others
- generalizes
GODEBUG=inittrace=1prints execution time and memory allocation for allinitcalls, e.g. to analyze startup time regressions- See State of Go @ FOSDEM 2021 for another overview of the additions and changes coming with this release
- 🏎️ the linker is faster, requires less memory and binaries are getting smaller as a result of more aggressive symbol pruning¹
- ¹ my naïve explanation of symbol pruning:
- a symbol contains metadata about the addresses of its variables and functions (source)
- 💡 you can show the symbols (symbol-table) of a binary using
nm <binary-file>(runningstrip <binary-file>will remove them all) - symbol pruning refers to the removal of symbols that are unused, e.g. uncalled functions from imported libraries
- initial pull request and go command support
- embed.go is only 423 lines including comments and blank lines
- strings are stored in plain-text in the binary
- embedded files must be located inside the package (that imports
embed) directory or its subdirectories - you can embed files as
string,[]byteorembed.FS- use
embed.FSwhen importing multiple (a tree of) files into a variable
- use
- using the embed directive requires to import
embedeven when usingstringor[]bytevariables (use blank import `import _ "embed") // go:embed pattern [pattern...]where paths usepath.Matchpatternsstringand[]bytecan only have a single pattern
- file patterns can be quoted like strings to embed paths containing spaces
- directories are embedded recursively while paths beginning with _ or . are excluded
- note that
// go:embed dir/*will embeddir/.foobut// go:embed dirwill not!
- note that
- patterns must not begin with ., .. or /
- invalid patters and matches (e.g. a symbolic link) will cause the compilation to fail
- embed directive can only be used with exported or unexported global variables at package scope
- run example:
source .env && go run ./cmd/embed :12345 - calling
stringson the binary shows that content is embedded as plain-text
- with
os.ReadDir/fs.ReadDirwe get to new functions for listing directory contents- those functions are a lot more efficient than
ioutil.ReadDirbecause they do not require to callstatfor each directory entry - for details see Ben Hoyts' article
- fun fact, those functions are inspired by Python's
os.scandir - to get the performance benefit of
ReadDirwhen walking directory trees you need to usefilepath.WalkDirinstead offilepath.Walk,filepath.WalkDirpassesfs.DirEntryinstead ofos.FileInfointo theWalkFn
- those functions are a lot more efficient than
type FS interface {
Open(name string) (File, error)
}io.FSfilesystem abstraction interface- prior art is
aferobut it has a much larger interface (and functionality, e.g. supports writes) embed.FSimplements this so you can easily work with embedded directory trees- pretty useful for tests, e.g. to prevent side effects →
testing/fstest.MapFSis an in-memory file system - accept
fs.FSand make your API filesystem agnostic, i.e. work transparently with a local directory, s3 block storage, remote file system etc. - 💡 you can easily test your custom file systems by passing them into
fstest.TestFS
- prior art is
type DeleteFS interface {
FS
Delete(name string) error
}- if you need more functionality use interface composition to build a larger interface, take ReadDirFS or
StatFSas an example
- depending on your personal opinion this might be good or bad news
- we will not see generics in a 1.x release
- Ardan Labs three part blog article series about generics
- (since some time already) there are two ways to try out generics:
- compile the
go2gotranslation tool from thedev.go2gobranch of the Go repo (instructions) - use the go2go playgound
- compile the
func print[T any](value T) {
fmt.Printf("type=%T\tvalue=%#v\n", value, value)
}
print([]int{1, 2, 3, 4})
print("Hello, Golang Leipzig!")[T any]is the type parameter listanyis a type constraint (limiting the set of allowed types that can be used forT)anymeans "unconstrained" or allow any type forT
type Number interface {
type int, float64
}
func sum[T, S Number](a T, b S) S {
return S(a) + b
}
sum(1, 3.1415)- a type parameter list can contain multiple type identifiers
- ... we will talk likely have a separate talk that covers Generics in depth