teivah / 100-go-mistakes Goto Github PK
View Code? Open in Web Editor NEWπ 100 Go Mistakes and How to Avoid Them
Home Page: https://100go.co/
License: Other
π 100 Go Mistakes and How to Avoid Them
Home Page: https://100go.co/
License: Other
There is a typo in the second to last sentence at the end of mistake 36:
Having these concepts in mind is essential because runes as are everywhere in Go. Let's see a concrete application of this knowledge involving a common mistake related to string iteration.
It would be useful if at the end of each mistake you listed which Go linters help catch the mistake (if any exist).
P.S. thanks for this project! I'm loving this book so far.
Knowing there will be a Chinese translation (release date unknown yet), I would very much like this repo to offer a Chinese version of the README.
If you're interested, feel free to open a PR, even if it's only one part of it :)
First off, thanks for creating and releasing this content, @teivah! Ive thoroughly enjoyed everything ive read thus far! Can't wait for my hard copy of your book to arrive.
I wasn't sure if these tag like markers (i.e. <1>
) were mistakenly included or not? I did not see them mentioned in text as if they were reference points, so I thought it was best to ask. Im happy to submit a PR to remove them if that is the case. JLMK.
100-go-mistakes/docs/9-generics.md
Lines 68 to 69 in 668d616
Func NewServer
is defined as:
func NewServer(addr string, config Config) (*http.Server, error)
... you can't pass nil as a config
param right?
You said this:
However, we still need to pass a
config struct that can be empty if a client wants to use the default configuration:
server, err := httplib.NewServer("localhost", nil)
Hello, first of all, please accept many thanks for the great book you wrote! It's awesome to have all those gotchas collected in one place and so well explained :)
I would like to ask for a further explanation of the statement in the book that made me a bit confused though. It says that the range
operator copies the slice/array/channel being iterated over (ie the range clause
) on its first (and only) evaluation just before the iteration. I cannot find that in the relevant part of the Golang spec. My understanding was, on the other hand, the for-range behaves that way because it's the v
(the local iterator variable) that is a copy of the slice element (not that the whole iterable thing gets copied). Please see the following snippet: https://go.dev/play/p/tEE8fW6Jxrk.
Referring to the code samples in this repo here, such a statement can be found in the book as the comment eg. to this one (or a couple of other snippets in the 4.2.x chapter):
Not a mistake in the book, but a question/suggestion. Would time.NewTicker
also help address the use case proposed by mistake #76? https://gobyexample.com/tickers
Not considering Fuzz test
Since go 1.18, this kind of tests may help us to find out missing edge case.
Solution
Use it ;) .
Any mentions of golang.org should be changed to go.dev to align with the ongoing site merge.
E.g. there is an occurrence on page 179.
Describe the book error
Hence, we defined K as comparable instead of a``ny
it should be any
need to fix directory name from 30-string-conversion to [40-string-conversion]
Item 22 says:
One of the main differences between a
nil
and an empty slice regards allocations. Initializing anil
slice doesnβt require any allocation, which isnβt the case for an empty slice.
Correct me if I am wrong, but AFAIK both slices will have no memory allocations.
Slices are represented in memory as 3 words, defined by the slice header:
type slice struct {
array unsafe.Pointer
len int
cap int
}
A nil
slice is actually a zero value of the slice header:
slice {
array: nil,
len: 0,
cap: 0,
}
An empty slice is just a slice with len
and cap
equal to 0 and an array
pointing to 'zero-sized' array:
slice {
array: unsafe.Pointer(&zerobase),
len: 0,
cap: 0,
}
The value of the array is the address of the runtime.zerobase
, the base address for all 0-byte allocations
Describe the mistake
Please add benchmark tests for 12-optimizations/91-cpu-caches/predictability
Solution
package main
import "testing"
const n = 1_000_000
var global int64
func BenchmarkLinkedList(b *testing.B) {
var local int64
for i := 0; i < b.N; i++ {
b.StopTimer()
nodes := make([]node, n)
for i := 0; i < n-1; i++ {
nodes[i].next = &nodes[i+1]
}
b.StartTimer()
local = linkedList(&nodes[0])
}
global = local
}
func BenchmarkSum2(b *testing.B) {
var local int64
for i := 0; i < b.N; i++ {
b.StopTimer()
s := make([]int64, n)
b.StartTimer()
local = sum2(s)
}
global = local
}
Unless I am missing something, the first code example in the "Implementing a function that receives a context" box on page 191 should have the Receive and Send labels switched to refer to the correct channel actions.
We should mention that from Go 1.21, there is a way to create a new context without cancel: https://pkg.go.dev/context#WithoutCancel
Originally posted by @AnhQuanTrl in #26 (comment)
Unless I am completely overlooking something, the customer
instantiations in the code example at the bottom of page 73 should not be indented.
See code example on page 282:
body, _ := ioutil.ReadAll(wordy)
should instead probably be something like
body, _ := io.ReadAll(w.Result().Body)
Describe the book error
Item #64 says: "disconnectCh
is a buffered channel", but it isn't.
hello, i find one spell mistake in 100-go-mistakes at chapter 9 #63 - Not being careful with goroutines and loop variable.
in the code, use fmt.Print :
s := []int{1, 2, 3}
for _, i := range s {
go func() {
fmt.Print(i)
}()
}
in the description, use fmt.Println:
it prints the value of i at the time fmt.Println is executed
As you may have noticed, I've been enriching the repo with much more content these past weeks. See https://100go.co.
I only had a TL;DR in the past, and now I want it to be as helpful as possible for people who can't afford to buy the book, for example.
It remains about one-third of the mistakes to summarize. Also, any suggestions or improvements to the existing system are more than welcome. The file to be modified is here: https://github.com/teivah/100-go-mistakes/blob/master/docs/index.md.
If you're up for it, feel free to open a PR (a PR could contain multiple mistakes summary). Let's keep track of the remaining work:
Translation of the main content in Portugese.
Reference: https://github.com/teivah/100-go-mistakes/blob/master/docs/index.md
Example: Japanese translation https://github.com/teivah/100-go-mistakes/blob/master/docs/ja.md
Advice: Step-wise approach (TL;DR blocks first, then the main content)
package main
import (
"context"
"fmt"
"time"
)
type detach struct{ ctx context.Context }
func (d detach) Deadline() (time.Time, bool) { return time.Time{}, false }
func (d detach) Done() <-chan struct{} { return nil }
func (d detach) Err() error { return nil }
func (d detach) Value(key any) any { return d.ctx.Value(key) }
func publish(ctx context.Context) {
select {
case <-ctx.Done():
fmt.Println(ctx.Err())
case <-time.After(100 * time.Millisecond):
fmt.Println("published")
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
defer cancel()
ctx = context.WithValue(ctx, "key", "value")
publish(detach{ctx: ctx}) // prints "published" even if the client timed out
}
Thanks.
On page 340, section Heap Profiling, high granularity means high rate, but instead it says:
We can change this rate, but we shouldn't be too granular because the more we decrease the rate, the more effort heap profiling will require to collect data.
Gophers in China are also interested in 100-go-mistakes-how-to-avoid-themοΌbut Chinese edition is not available yet. I wish to get your authorization to translate it into Chinese and publish it on Github for free. Thanks a lot @teivah
10.1 #75 Providing a wrong time duration should stop ticker, or cause leaks
ticker := time.NewTicker(1000) // should stop defer
for {
select {
case <-ticker.C:
// Do something
}
}
ticker := time.NewTicker(1000)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// Do something
}
}
At the top of page 303 the brackets for resolving the s
at Index 8:
Again, accessing
s8
results...
Knowing there will be a Japanese translation (released in August 2023), I would very much like this repo to offer a Japanese version of the README.
If you're interested, feel free to open a PR, even if it's only one part of it :)
EDIT: The work has been started (thanks to @rustinwelter), the page is here: https://github.com/teivah/100-go-mistakes/blob/master/docs/ja.md
which we will implement, is to return the rows.Scan error but log the rows.Close error
vs
so we decide to log "err" and return the existing error.
so we decide to log "closeErr" and return the existing error.
100-go-mistakes/07-error-management/54-defer-errors/main.go
Lines 32 to 50 in b2152d0
log.Printf("failed to close rows: %v", closeErr)
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.