Last active
November 12, 2025 20:34
-
-
Save danhodge/f234a6baf9da695c9ddd17f831d9dc2a to your computer and use it in GitHub Desktop.
Revisions
-
danhodge revised this gist
Nov 12, 2025 . 1 changed file with 22 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -105,6 +105,28 @@ fn = TakesIntReturnsString TakesDoer(fn, 8) // implement a function with an interface // 1. given some interface type MyInterface interface { DoIt(string) (string, error) // many other functions } // 2. define a function type for one of the functions type MyFunc func(string) (string, error) // 3. create a instance of the interface thing := MyThing{} // implements MyInterface // 4. access the method var fn MyFunc fn = thing.DoIt // implement a function that captures state without using a struct type Searcher func(q string) string -
danhodge revised this gist
Oct 22, 2025 . No changes.There are no files selected for viewing
-
danhodge revised this gist
Oct 22, 2025 . 1 changed file with 12 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -104,6 +104,18 @@ fn = TakesIntReturnsString // 5. Pass it into the function from step 3 TakesDoer(fn, 8) // implement a function that captures state without using a struct type Searcher func(q string) string func NewSearcher(client *search.client) Searcher { return func(q string) string { return client.SearchQuery(q) } } // Shorthand for passing an error (or any other local variable) into a deferred function func somefunc() (_ int, err error) { // use an _ for the unnamed return value - all values have to be named when using named values -
danhodge revised this gist
Oct 2, 2025 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -118,6 +118,26 @@ func somefunc() (_ int, err error) { // use an _ for the unnamed return value - // do stuff that may or may not result in err being set } // the only way to modify a return value from a deferred function is using named parameters // returns 0 func f() int { res := 0 defer func(){ res++ }() return res } // returns 1 func f() (res int) { res = 0 defer func(){ res++ }() return res } // struct embedding + methods & "inheritance" type Base struct { -
danhodge revised this gist
Sep 24, 2025 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -156,6 +156,8 @@ func main() { } // Check to see if an error chain includes a particular error // Note: the type of p needs to correspond to the receiver type for the Error() method on SomeErrorType // meaning, if Error() has a pointer receiver on SomeErrorType, p needs to be a pointer, otherwise, it needs to be a value var p *SomeErrorType errors.As(err, &p) @@ -578,3 +580,21 @@ func (m *MyThing) Produce(msg string) error { } return nil } // Method Sets // from: https://stackoverflow.com/a/33591156 /* 1. If you have a *T you can call methods that have a receiver type of *T as well as methods that have a receiver type of T. 2. If you have a T and it is addressable you can call methods that have a receiver type of *T as well as methods that have a receiver type of T, because the method call t.Meth() will be equivalent to (&t).Meth() (Calls). 3. If you have a T and it isn't addressable (for instance, the result of a function call, or the result of indexing into a map), Go can't get a pointer to it, so you can only call methods that have a receiver type of T, not *T. 4. If you have an interface I, and some or all of the methods in I's method set are provided by methods with a receiver of *T (with the remainder being provided by methods with a receiver of T), then *T satisfies the interface I, but T doesn't. That is because *T's method set includes T's, but not the other way around (back to the first point again). In short, you can mix and match methods with value receivers and methods with pointer receivers, and use them with variables containing values and pointers, without worrying about which is which. Both will work, and the syntax is the same. However, if methods with pointer receivers are needed to satisfy an interface, then only a pointer will be assignable to the interface — a value won't be valid. */ -
danhodge revised this gist
Sep 12, 2025 . 1 changed file with 23 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -555,4 +555,26 @@ func main() { v := <-ch fmt.Printf("r = %d, err = %v\n", v.r, v.err) } // how to override a method in a test without using interfaces or mocks - somewhat contrived example // some external dependency that defines the method named "Produce" that needs to be mocked type ExternalDependency struct { } // my_code.go type MyThing { ExternalDependency } // my_code_test.go var fakeProducer func(string) error // tests will use this version of the Produce function, which exposes a hook function for spying/mocking func (m *MyThing) Produce(msg string) error { if fakeProducer != nil { return fakeProducer(msg) } return nil } -
danhodge revised this gist
Jun 2, 2025 . 1 changed file with 24 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -532,4 +532,27 @@ func TakesIdentifiable[T Identifiable](seq iter.Seq[T]) { fmt.Printf(val) } } TakesIdentifiable(slices.Values([]ValueThing{ValueThing{Id: "123"}, ValueThing{Id: "456"}})) // "return" a value, err from a goroutine func DoStuff() (int, error) { return 12, errors.New("error") } func main() { ch := make(chan struct { r int err error }, 1) go func() { r, err := DoStuff() ch <- struct { r int err error }{r, err} }() v := <-ch fmt.Printf("r = %d, err = %v\n", v.r, v.err) } -
danhodge revised this gist
Apr 4, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -526,7 +526,7 @@ TakesIdentifiable(&pt) // Go does not support covariance on slices, so this doesn't compile var slc = []Identifable{ValueThing{Id: "123"}, ValueThing{Id: "456"}} // range over func can be used to pass an slice of concrete types as a parameter to a function that takes an interface type func TakesIdentifiable[T Identifiable](seq iter.Seq[T]) { for val := range seq { fmt.Printf(val) -
danhodge revised this gist
Apr 4, 2025 . 1 changed file with 9 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -523,6 +523,13 @@ TakesIdentifiable(pt) // compiles since the argument is now a *PointerThing, which does satisfy the Identifiable interface TakesIdentifiable(&pt) // Go does not support covariance on slices, so this doesn't compile var slc = []Identifable{ValueThing{Id: "123"}, ValueThing{Id: "456"}} // range over func can be used to pass an array concrete type as a parameter to a function that takes an interface type func TakesIdentifiable[T Identifiable](seq iter.Seq[T]) { for val := range seq { fmt.Printf(val) } } TakesIdentifiable(slices.Values([]ValueThing{ValueThing{Id: "123"}, ValueThing{Id: "456"}})) -
danhodge revised this gist
Apr 4, 2025 . 1 changed file with 36 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -488,5 +488,41 @@ fmt.Printf("%v\n", s) // prints [] sub := s[0:2] fmt.Printf("%v\n", sub) // prints [A B] // interface satisfaction // given this interface type Identifiable interface { GetId() string } // and these implementations type ValueThing struct { Id string } func (t ValueThing) GetId() string { return t.Id } type PointerThing struct { Id string } func (t *PointerThing) GetId() string { return t.Id } vt := ValueThing{Id: "123"} pt := PointerThing{Id: "456"} // compiles TakesIdentifiable(vt) // does not compile because PointerThing does not implement the Identifiable, *PointerThing does (due to pointer receiver) TakesIdentifiable(pt) // compiles since the argument is now a *PointerThing, which does satisfy the Identifiable interface TakesIdentifiable(&pt) -
danhodge revised this gist
Mar 26, 2025 . 1 changed file with 15 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -473,5 +473,20 @@ s := []string{} var m map[string]string var s []string{} // clearing a slice var s []string s = append(s, "A") s = append(s, "B") s = append(s, "C") // this clears the slice by setting len = 0 but it doesn't remove any of the elements s = s[:0] fmt.Printf("%v\n", s) // prints [] // you can still create a subslice from s up to the slice's existing capacity, which will include the existing elements sub := s[0:2] fmt.Printf("%v\n", sub) // prints [A B] -
danhodge revised this gist
Mar 7, 2025 . 1 changed file with 13 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -462,3 +462,16 @@ func main() { fmt.Printf("t2 = %v\n", t2) } // initializing slices & maps // these both allocate empty data structures that can have keys/values added to them m := map[string]string{} s := []string{} // these don't allocate any storage and are nil // nil slices can be appended to using the append function but nil maps can't accept keys/values var m map[string]string var s []string{} -
danhodge revised this gist
Jan 20, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ // types and literals // defines a new type (note - this is not a type alias, type aliases are a different thing, defined by: type ALIAS = ORIGNAL) type Thing int32 // this function only accepts arguments of type Thing, int32 arguments are not allowed by the compiler -
danhodge revised this gist
Jan 20, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ // types and literals // defines a new type (note - this is not a type alias, type aliases are a different thing, defined by type ALIAS = ORIGNAL) type Thing int32 // this function only accepts arguments of type Thing, int32 arguments are not allowed by the compiler -
danhodge revised this gist
Nov 13, 2024 . 1 changed file with 31 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -431,3 +431,34 @@ payload = `{"identifier": "1234"}` type Thing struct { Id int `json:identifier,string` } // Closures are able to capture local variables type Thing struct { Val string } func Run(fn func()) { fn() } func NewThing(v string) Thing { return Thing{Val: v} } func main() { t1 := Thing{Val: "123"} Run(func() { // can modify locals from a closure t1.Val = "456" }) fmt.Printf("t1 = %v\n", t1) t2 := Thing{} Run(func() { // can reassign locals from a closure t2 = NewThing("789") }) fmt.Printf("t2 = %v\n", t2) } -
danhodge revised this gist
Oct 22, 2024 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -236,7 +236,8 @@ type structName struct {} // fails to compile due to no: func (s *structName) Func1(s string) string { return "val" } // what is this doing? // declares a variable of type Interface name (that we don't care about so it's assigned to _) // and tries assigning a variable of type pointer to structName to it and the assignment will fail // if structName does not implement all of the methods defined on InterfaceName // - uses nil because nil can be assigned to any pointer so no need to declare a structName variable // - uses a pointer because it is idiomatic to use pointer receivers when defining methods, if you could // guarantee that structName would never need to use pointer receivers, you could achieve the same thing -
danhodge revised this gist
Oct 22, 2024 . 1 changed file with 8 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -231,9 +231,16 @@ type InterfaceName { Func1(s string) string } type structName struct {} // fails to compile due to no: func (s *structName) Func1(s string) string { return "val" } // what is this doing? // declares a variable of type Interface name (that we don't care about so it's assigned to _) // and tries assigning a variable of type pointer to structName // - uses nil because nil can be assigned to any pointer so no need to declare a structName variable // - uses a pointer because it is idiomatic to use pointer receivers when defining methods, if you could // guarantee that structName would never need to use pointer receivers, you could achieve the same thing // by assinging a zero value of structName to an InterfaceName variable. var _ InterfaceName = (*structName)(nil) // JSON marshaling omit attributes if not set -
danhodge revised this gist
Oct 18, 2024 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -415,3 +415,11 @@ func main() { fmt.Printf("Result: %s\n", s) } } // Deserialize JSON string as int payload = `{"identifier": "1234"}` type Thing struct { Id int `json:identifier,string` } -
danhodge revised this gist
Oct 18, 2024 . 1 changed file with 31 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -384,4 +384,34 @@ func main() { } // print full struct info (FQN & field names/values) fmt.Printf("%#v", val) // channels and go routines // https://go.dev/play/p/SwLwKziIb_A func work(num int) string { return fmt.Sprintf("Job: %d", num) } func main() { ct := 10 ch := make(chan string, ct) var wg sync.WaitGroup for i := range ct { wg.Add(1) go func() error { defer wg.Done() ch <- work(i) return nil }() } wg.Wait() // wait for all goroutines to finish close(ch) // close the results channel (otherwise, range loop will never terminate) for s := range ch { fmt.Printf("Result: %s\n", s) } } -
danhodge revised this gist
Jul 2, 2024 . 1 changed file with 8 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -236,6 +236,14 @@ type structName {} // fails to compile due to no: func (s *structName) Func1(s string) string { return "val" } var _ InterfaceName = (*structName)(nil) // JSON marshaling omit attributes if not set type Thing struct { Value1 string `json:"value1"` // marshals "value1": "" if not set Value2 string `json:"value2,omitempty"` // omits "value1" if not set or set to "" Value3 *string `json:"value3"` // marshals "value1": null if not set Value4 *string `json:"value4,omitempty"` // omits "value1" if not set or set to nil } // Custom JSON unmarshaling with validation: https://go.dev/play/p/jYPARNjmhVn -
danhodge revised this gist
Jun 3, 2024 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -304,11 +304,13 @@ type Descriptor struct { } func (a *Descriptor) UnmarshalJSON(data []byte) error { // need to use a different type definition here (desc2 instead of Descriptor) to avoid infinite recursion during unmarshaling type desc2 Descriptor tmp := struct { BaseURL string `json:"baseUrl"` *desc2 }{ // embeds a pointer to the receiver in this anonymous struct to receive the other attributes as is desc2: (*desc2)(a), } -
danhodge revised this gist
May 20, 2024 . 1 changed file with 34 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -293,6 +293,40 @@ func main() { } } // custom JSON unmarshaling using an embedded struct to separate custom & default parsing // https://ukiahsmith.com/blog/improved-golang-unmarshal-json-with-time-and-url/ type Descriptor struct { Name string `json:"name"` Key string `json:"key"` Description string `json:"description"` BaseURL url.URL `json:"baseUrl"` } func (a *Descriptor) UnmarshalJSON(data []byte) error { type desc2 Descriptor tmp := struct { BaseURL string `json:"baseUrl"` *desc2 }{ desc2: (*desc2)(a), } err := json.Unmarshal(data, &tmp) if err != nil { return err } baseURL, err := url.Parse(tmp.BaseURL) if err != nil { return err } a.BaseURL = *baseURL return nil } // embedding an interface in a struct can be used for delegation // https://go.dev/play/p/xnmxLdCXjqL -
danhodge revised this gist
May 10, 2024 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -337,4 +337,7 @@ func main() { wt := WrappedThing(t, 17) fmt.Printf("%d, %d\n", wt.Increase(n), wt.Decrease(n)) } // print full struct info (FQN & field names/values) fmt.Printf("%#v", val) -
danhodge revised this gist
May 1, 2024 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -294,6 +294,7 @@ func main() { } // embedding an interface in a struct can be used for delegation // https://go.dev/play/p/xnmxLdCXjqL // the common interface type Thing interface { -
danhodge revised this gist
May 1, 2024 . 1 changed file with 44 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -293,3 +293,47 @@ func main() { } } // embedding an interface in a struct can be used for delegation // the common interface type Thing interface { Increase(i int32) int32 Decrease(i int32) int32 } // the base implementation type thing struct{} func (t thing) Increase(i int32) int32 { return i + 10 } func (t thing) Decrease(i int32) int32 { return i - 10 } // the wrapped implementation (embeds the common interface) type Wrapped struct { Thing Amount int32 } // changes the Increase method to delegate to the base // implementation and then do something else func (w Wrapped) Increase(i int32) int32 { return w.Thing.Increase(i) + w.Amount } // wraps a base implementation in the wrapped implementation func WrappedThing(thing Thing, amt int32) Thing { return &Wrapped{thing, amt} } func main() { var n int32 = 20 t := thing{} fmt.Printf("%d, %d\n", t.Increase(n), t.Decrease(n)) wt := WrappedThing(t, 17) fmt.Printf("%d, %d\n", wt.Increase(n), wt.Decrease(n)) } -
danhodge revised this gist
Mar 26, 2024 . 1 changed file with 59 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -234,4 +234,62 @@ type InterfaceName { type structName {} // fails to compile due to no: func (s *structName) Func1(s string) string { return "val" } var _ InterfaceName = (*structName)(nil) // Custom JSON unmarshaling with validation: https://go.dev/play/p/jYPARNjmhVn type Outer struct { Name string `json:"name"` Things []Inner `json:"things"` } func (o *Outer) UnmarshalJSON(b []byte) error { var raw map[string]json.RawMessage if err := json.Unmarshal(b, &raw); err != nil { return err } if err := json.Unmarshal(raw["name"], &o.Name); err != nil { return err } if err := json.Unmarshal(raw["things"], &o.Things); err != nil { return err } return nil } type Inner struct { Value int32 `json:"val"` } func (i *Inner) UnmarshalJSON(b []byte) error { var raw map[string]json.RawMessage if err := json.Unmarshal(b, &raw); err != nil { return err } if err := json.Unmarshal(raw["val"], &i.Value); err != nil { return err } if i.Value < 100 { return errors.New("Too Low") } return nil } func main() { var x Outer str := `{"name": "Me", "things": [{ "val": 120 }, { "val": 30 }]}` err := json.Unmarshal([]byte(str), &x) if err != nil { // fails because val=30 is < 100 fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Value: %+v\n", x) } } -
danhodge revised this gist
Feb 1, 2024 . 1 changed file with 12 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -223,4 +223,15 @@ func main() { } else { fmt.Printf("OK: %v\n", val) } } // force a compile-time error if a struct doesn't fully implement a given interface type InterfaceName { Func1(s string) string } type structName {} // fails to compile due to no: func (s *structName) Func1(s string) string { return "val" } var _ InterfaceName = (*structName)(nil) -
danhodge revised this gist
Oct 25, 2023 . 1 changed file with 34 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -190,4 +190,37 @@ defer cancel2() // the deadline for ctx1a will override the parent context's deadline because 5ms < 10ms ctx1a, cancel1a := context.WithDeadline(ctx1, time.Now().Add(time.Duration(5)*time.Millisecond)) defer cancel1a() // json.NewDecoder() ignores garbage at the end of the stream type Thing struct { Name string `json:"name"` } func parse1(stream io.ReadCloser) (Thing, error) { t := Thing{} buf := new(bytes.Buffer) if _, err := buf.ReadFrom(stream); err != nil { return t, err } err := json.Unmarshal(buf.Bytes(), &t) return t, err } func parse2(stream io.ReadCloser) (Thing, error) { t := Thing{} err := json.NewDecoder(stream).Decode(&t) return t, err } func main() { // parse1 fails, parse2 succeeds val, err := parse1(io.NopCloser(strings.NewReader(`{"name":"Bob"}PLUS GARBAGE`))) if err != nil { fmt.Printf("Error happened: %v\n", err) } else { fmt.Printf("OK: %v\n", val) } } -
danhodge revised this gist
Sep 29, 2023 . No changes.There are no files selected for viewing
-
danhodge revised this gist
Sep 29, 2023 . 1 changed file with 15 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -176,4 +176,18 @@ func genericFunction[T any]() (T, error) { ctx, cancel := context.WithDeadline(ctx, time.Now().Add(time.Duration(deadline) * time.Millisecond)) defer cancel() conn.Operation(ctx, ...) // when setting deadlines, the earliest deadline takes precedence root := context.Background() ctx1, cancel1 := context.WithDeadline(root, time.Now().Add(time.Duration(10)*time.Millisecond)) defer cancel1() // the deadline for ctx2 will not override the parent context's deadline because 10ms < 10s ctx2, cancel2 := context.WithDeadline(ctx1, time.Now().Add(time.Duration(10)*time.Second)) defer cancel2() // the deadline for ctx1a will override the parent context's deadline because 5ms < 10ms ctx1a, cancel1a := context.WithDeadline(ctx1, time.Now().Add(time.Duration(5)*time.Millisecond)) defer cancel1a()
NewerOlder