Решил записать несколько моментов, с которыми столкнулся при изучении Go, но не видел в статьях и учебниках.
Нельзя просто так взять и передать
uint8
в функцию, которая принимаетint32
. Или int в качествеint64
. Или сложить их между собой. То есть, приведения типов нет даже для таких вот простых случаев. Где критична память, используйте наиболее подходящие типы и приводите их явно, когда это нужно. Где микрооптимизации не нужны (всегда и везде, то есть) используйтеint
иfloat64
. Если посмотреть на функции в стандартной библиотеке, там везде так сделано. Например, где принимается индекс элемента в массиве, это всегдаint
, хотя отрицательным это значение быть не может.Если метод в struct завязан на указатель на этот struct и вы делаете интерфейс для этого, то надо работать с указателем на struct. На словах вообще непонятно, вот пример:
String() string
}
type MyType struct {
value string
}
func (m *MyType) String() string { return m.value }
mt := MyType{"test"}```
Теперь в функции, принимающие интерфейс Stringer надо передавать не `mt`, а `&mt`. Сообщение об ошибке было непонятное, так что чёт запомнилось.
3. Корутины дешёвые, но их нельзя делать сколько угодно! Ну то есть с горутинами всё отлично, а вот БД или сетевой интерфейс можно зафлудить. Например, нужно нам вытащить 1000 страниц с какого-то сайта. Делаем для каждой страницы горутину и получаем `socket: too many open files`. Так что делаем корутин 10-50, в каждую передаем канал с задачами, которые нужно выполнить, а снаружи пихаем туда, что нужно сделать:
```func example(data int) {
wg := sync.WaitGroup{}
worker := func(jobs <-chan int) {
wg.Add(1)
for someNumber := range jobs {
// do something
}
wg.Done()
}
// spawn 10 workers
jobs := make(chan int, len(data))
for i := 0; i < 10; i++ {
go worker(jobs)
}
// add jobs
for _, el := range data {
jobs <- el
}
close(jobs)
wg.Wait()
}```
Если ищете, с чего начать изучать Go, у меня было несколько постов про это:
+ <https://t.me/itgram_channel/79>
+ <https://t.me/itgram_channel/100>