-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
13cfdac
commit e0a85c4
Showing
7 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# The Globus BB Gophers Meetup | ||
|
||
Cyrill Schumacher | ||
Magazine zum Globus AG | ||
|
||
## Welcome | ||
|
||
Thank you for joining! | ||
|
||
.image 2017-08-10/GoCommunity.png _ 700 | ||
.caption _Gopher_ by [[http://www.reneefrench.com][Renée French]] | ||
.caption _Graphics_ by [[https://github.com/ashleymcnamara][Ashley McNamara]] | ||
|
||
## Let's go! | ||
|
||
.image 2017-08-10/Unicorn_Gopher.png _ 400 | ||
.caption _Gopher_ by [[http://www.reneefrench.com][Renée French]] | ||
.caption _Graphics_ by [[https://github.com/ashleymcnamara][Ashley McNamara]] | ||
|
||
## Go 1.18 main new features | ||
|
||
- new support for generic code using parameterized types. | ||
- adds built-in support for writing fuzzing-based tests, to automatically find | ||
inputs that cause your program to crash or return invalid answers. | ||
- adds a new “Go workspace mode”, which lets you work with multiple Go modules | ||
simultaneously, an important use case for larger projects. | ||
- contains an expanded go version -m command, which now records build details | ||
such as compiler flags. A program can query its own build details using | ||
debug.ReadBuildInfo, and it can now read build details from other binaries using | ||
the new debug/buildinfo package. This functionality is meant to be the foundation | ||
for any tool that needs to produce a software bill of materials (SBOM) for Go | ||
binaries. | ||
|
||
## Fuzzing | ||
|
||
.link https://go.dev/blog/fuzz-beta | ||
Fuzzing is a type of automated testing which continuously manipulates inputs to a | ||
program to find issues such as panics or bugs. These semi-random data mutations | ||
can discover new code coverage that existing unit tests may miss, and uncover | ||
edge case bugs which would otherwise go unnoticed. | ||
|
||
.code 2021-02-04/parse_fuzz.go | ||
|
||
|
||
## Workspace mode | ||
|
||
.link https://go.googlesource.com/proposal/+/master/design/45713-workspace.md | ||
A new workspace mode in the go command for editing multiple modules has been | ||
added. The presence of a go.work file in the working directory or a containing | ||
directory will put the go command into workspace mode. The go.work file specifies | ||
a set of local modules that comprise a workspace. When invoked in workspace mode, | ||
the go command will always select these modules and a consistent set of | ||
dependencies. | ||
|
||
## Parameterized types | ||
|
||
.link https://go.dev/doc/tutorial/generics | ||
|
||
Generics are the most significant change to Go since the release of Go 1, and | ||
certainly the largest single language change the Go team have ever made. | ||
|
||
## Generics gotchas "return" | ||
|
||
.play -edit -numbers 2021-02-04/generic_gotcha_return.go | ||
|
||
## Generics gotchas "fmt" 1/2 | ||
|
||
.play -edit -numbers 2021-02-04/generic_gotcha_fmt.go | ||
|
||
## Generics gotchas "fmt" 2/2 | ||
|
||
the go vet error results in: | ||
|
||
$ go vet generic_gotcha_fmt.go | ||
./generic_gotcha_fmt.go:12:20: fmt.Errorf format %q has arg key of wrong type K | ||
|
||
Solution is... | ||
|
||
## Generics Interface with type constraints (Problem) | ||
|
||
.play -numbers 2021-02-04/generic_gotcha_interface_type_constraint01.go | ||
|
||
## Generics Interface with type constraints (Solution) | ||
|
||
.play -numbers 2021-02-04/generic_gotcha_interface_type_constraint02.go | ||
|
||
## Unusual Generics | ||
|
||
// Ptr is a simple function that helps to get literal pointer in one-line. | ||
func Ptr[T any](v T) *T { return &v } | ||
|
||
Invoked as: | ||
|
||
pInt := unusual_generics.Ptr(10) | ||
pStr := unusual_generics.Ptr("test") | ||
pUint64 := unusual_generics.Ptr[uint64](24) | ||
fmt.Printf("%[1]T %[1]d\n", *pInt) | ||
fmt.Printf("%[1]T %[1]s\n", *pStr) | ||
fmt.Printf("%[1]T %[1]d\n", *pUint64) | ||
// Output: | ||
// int 10 | ||
// string test | ||
// uint64 24 | ||
|
||
Attention: future version Go can call directly `&10` or `&"test"`. | ||
|
||
## Generic constraints for checks during compile time | ||
|
||
.play -edit -numbers 2021-02-04/generic_avoidnil.go | ||
|
||
## Generics: bad patterns | ||
|
||
pointing out that: | ||
``` | ||
func Something[R io.Reader](r R) error { ... } | ||
``` | ||
is a useless use of generics and that is correctly written as: | ||
``` | ||
func Something(r io.Reader) error { ... } | ||
``` | ||
|
||
## When to use Generics? | ||
|
||
Use them wisely where multiple types occur and not just one. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
) | ||
|
||
// https://github.com/golang/go/issues/45346 | ||
// Section: Combining embedded non-interfaces with methods | ||
type TimeLayoutProvider interface { | ||
~struct{} // constrain base type to avoid runtime errors on zero-value method calls | ||
TimeLayout() string | ||
} | ||
|
||
type TimeFormatted[T TimeLayoutProvider] time.Time | ||
|
||
func (tf TimeFormatted[T]) MarshalText() ([]byte, error) { | ||
var p T | ||
t := time.Time(tf) | ||
return []byte(t.Format(p.TimeLayout())), nil | ||
} | ||
|
||
type formatXYZProvider struct{} | ||
|
||
func (formatXYZProvider) TimeLayout() string { return "2006 Jan _2 15:04:05 -0700" } | ||
|
||
func main() { | ||
now := time.Now() | ||
//layout := TimeFormatted[formatXYZProvider](now) | ||
tf := TimeFormatted[formatXYZProvider](now) | ||
raw, _ := tf.MarshalText() | ||
fmt.Println(string(raw)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package main | ||
|
||
import "fmt" | ||
|
||
type FooBar[K comparable, V any] struct { | ||
cache map[K]V | ||
} | ||
|
||
func (fb FooBar[K, V]) getKey(key K) (emptyVal V, _ error) { | ||
val, ok := fb.cache[key] | ||
if !ok { | ||
return emptyVal, fmt.Errorf("key %q not found", key) | ||
} | ||
return val, nil | ||
} | ||
func main() { | ||
fb := FooBar[int, []byte]{cache: make(map[int][]byte)} // OMIT | ||
_, err := fb.getKey(3) // OMIT | ||
fmt.Println(err.Error()) // OMIT | ||
} |
37 changes: 37 additions & 0 deletions
37
static/talks/2021-02-04/generic_gotcha_interface_type_constraint01.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package main | ||
|
||
//OMIT | ||
import "fmt" | ||
|
||
//OMIT | ||
func main() { | ||
c := Car{Name: "Ferrari"} | ||
Move(c, 100, 20) | ||
} | ||
|
||
//OMIT | ||
// Subtractable is a type constraint that defines subtractable datatypes to be | ||
// used in generic functions. | ||
type Subtractable interface { | ||
int | int32 | int64 | float32 | float64 | uint | uint32 | uint64 | ||
} | ||
|
||
//OMIT | ||
// Moveable is a interface that is used to handle many objects that are moveable | ||
type Moveable interface { | ||
Move(Subtractable) | ||
} | ||
|
||
//OMIT | ||
// Car is a test struct for cars, implements Moveable | ||
type Car struct{ Name string } | ||
|
||
//OMIT | ||
func (c Car) Move(meters Subtractable) { fmt.Printf("%s moved %d meters\n", c.Name, meters) } | ||
|
||
//OMIT | ||
// Move is a generic function that takes in a Moveable and moves it | ||
func Move[V Moveable, D Subtractable](v V, distance D, meters D) D { | ||
v.Move(meters) | ||
return distance - meters | ||
} |
37 changes: 37 additions & 0 deletions
37
static/talks/2021-02-04/generic_gotcha_interface_type_constraint02.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package main | ||
|
||
//OMIT | ||
import "fmt" | ||
|
||
//OMIT | ||
func main() { | ||
c := Car[int]{Name: "Ferrari"} | ||
Move(c, 100, 20) | ||
} | ||
|
||
//OMIT | ||
// Subtractable is a type constraint that defines subtractable datatypes to be | ||
// used in generic functions. | ||
type Subtractable interface { | ||
~int | ~int32 | ~int64 | float32 | float64 | uint | uint32 | uint64 | ||
} | ||
|
||
//OMIT | ||
// Moveable is a interface that is used to handle many objects that are moveable | ||
type Moveable[S Subtractable] interface { | ||
Move(S) | ||
} | ||
|
||
//OMIT | ||
// Car is a test struct for cars, implements Moveable | ||
type Car[S Subtractable] struct{ Name string } | ||
|
||
//OMIT | ||
func (c Car[S]) Move(meters S) { fmt.Printf("%s moved %v meters\n", c.Name, meters) } | ||
|
||
//OMIT | ||
// Move is a generic function that takes in a Moveable and moves it | ||
func Move[D Subtractable, V Moveable[D]](v V, distance D, meters D) D { | ||
v.Move(meters) | ||
return distance - meters | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
) | ||
|
||
type FooBar2[K comparable, V any] struct { | ||
cache map[K]V | ||
} | ||
|
||
func (fb FooBar2[K, V]) getKey(key K) (V, error) { | ||
val, ok := fb.cache[key] | ||
if !ok { | ||
return nil, errors.New("key not found") | ||
} | ||
return val, nil | ||
} | ||
func main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package main // OMIT | ||
|
||
import ( // OMIT | ||
"net/url" // OMIT | ||
"reflect" // OMIT | ||
"testing" // OMIT | ||
) // OMIT | ||
// OMIT | ||
func FuzzParseQuery(f *testing.F) { | ||
f.Add("x=1&y=2") | ||
f.Fuzz(func(t *testing.T, queryStr string) { | ||
query, err := url.ParseQuery(queryStr) | ||
if err != nil { | ||
t.Skip() | ||
} | ||
queryStr2 := query.Encode() | ||
query2, err := url.ParseQuery(queryStr2) | ||
if err != nil { | ||
t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err) | ||
} | ||
if !reflect.DeepEqual(query, query2) { | ||
t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2) | ||
} | ||
}) | ||
} |