Irbisa · Шпаргалка
Основы Go
Синтаксис, нулевые значения, константы и iota, control flow, defer и замыкания
Что такое Go, зачем его создали и какие у него главные сильные и слабые стороны?
Какие привычные возможности Go намеренно не поддерживает (тернарный оператор,
while, наследование, исключения, перегрузку) и что использует вместо них?Что такое пакет в Go, как его импортировать и что делает имя экспортируемым?
// store/store.go, in module example.com/apppackage store type Row struct { ID int // exported: visible to other packages and to encoding/json name string // unexported: visible only inside package store…Чем отличаются
go run,go buildиgo install?Какими способами объявляют переменную в Go и где можно использовать
:=?var build = "dev" // package level: `build := "dev"` here is a syntax error func load(path string) error { var rows []Row // no value yet: the zero value (a nil slice) is what we want var id uint64 = 7 // := would have inferred int…Что такое нулевое значение (zero value) в Go и какое оно у чисел, строк, указателей, слайсов, map, каналов и структур?
type Server struct { Addr string // "" Port int // 0 mu sync.Mutex // ready to use, no constructor buf bytes.Buffer // same tags []string // nil…Что такое константы и
iotaв Go и как написать enum?type State uint8 const ( StateUnknown State = iota // 0, also the zero value of State StatePending // 1: the line repeats `State = iota` StateRunning // 2…Какой размер у
intв Go и что происходит при целочисленном переполнении и делении на ноль?func main() { defer func() { fmt.Println("recovered:", recover()) }() fmt.Println(strconv.IntSize) // 64 on amd64 and arm64 var a int8 = 127…Как в Go работает преобразование типов и почему нет неявного преобразования между числовыми типами?
done, total := 3, 4fmt.Println(done / total * 100) // 0: integer division firstfmt.Println(float64(done/total) * 100) // 0: converted too latefmt.Println(float64(done) / float64(total) * 100) // 75 v, f, n := 300, 3.9, -1…Какие формы принимает цикл
forв Go и по чему может итерироватьсяrange?for i := 0; i < 3; i++ { // three-clause fmt.Print(i)} for rows.Next() { // condition only: Go's while scan(rows)…Что напечатает этот цикл и как сделать так, чтобы
breakостанавливал цикл?jobs := []string{"a", "stop", "b"}for _, j := range jobs { switch j { case "stop": fmt.Println("stopping") break default: fmt.Println("run", j) }}Как в Go работают несколько возвращаемых значений и для чего нужен пустой идентификатор
_?func divmod(a, b int) (int, int, error) { if b == 0 { return 0, 0, errors.New("division by zero") } return a / b, a % b, nil}…Что такое вариативная функция и как передать в неё слайс?
func sum(xs ...int) int { total := 0 for _, x := range xs { total += x } return total…Как в Go передаются аргументы в функцию и когда передавать указатель вместо значения?
type Config struct { Addr string Timeout time.Duration} func setTimeoutCopy(c Config) { // wrong: changes a copy…Чем отличаются
makeиnew?p := new(int) // *int pointing at 0u := &User{Name: "ada"} // *User with fields set: the usual choicem := make(map[string]int) // ready for writess := make([]int, 0, 100) // len 0, cap 100ch := make(chan int, 10) // buffered channel…Как работает
defer: когда выполняются отложенные вызовы, в каком порядке и когда вычисляются их аргументы?func countdown() { for i := 0; i < 3; i++ { defer fmt.Print(i, " ") // i is evaluated now, the call runs at return }} // prints 2 1 0…Чем отличаются
fmt.Println,fmt.Printfиfmt.Sprintfи что печатают%v,%+v,%#v,%Tи%q?type User struct { ID int Name string} func main() {…Этот хелпер перебирает несколько URL и логирует каждый неудачный, но возвращает
nil, даже когда все они провалились. Почему и почему компилятор молчит?func fetch(urls []string) error { var err error for _, u := range urls { if resp, err := http.Get(u); err != nil { log.Printf("attempt %s: %v", u, err) } else { resp.Body.Close() return nil } } return err}Найдите баг:
lastNвозвращает верные элементы при малыхn, но паникует сindex out of range, когдаnравноlen(xs).func lastN(xs []int, n uint) []int { var out []int for i := uint(len(xs)) - 1; i >= uint(len(xs))-n; i-- { out = append(out, xs[i]) } return out}Что вернёт
f()и что бы она вернула, если бы результат не был именованным?func f() (n int) { defer func() { n *= 2 }() n = 1 return n + 2}Найдите баг:
hashAllпроходит тесты, но в продакшене на больших директориях падает сtoo many open files.func hashAll(paths []string) (map[string]string, error) { sums := make(map[string]string, len(paths)) for _, p := range paths { f, err := os.Open(p) if err != nil { return nil, err } defer f.Close() h := sha256.New() if _, err := io.Copy(h, f); err != nil { return nil, err } sums[p] = hex.EncodeToString(h.Sum(nil)) } return sums, nil}Что такое замыкание в Go и как Go 1.22 изменил то, что замыкания захватывают внутри цикла
for?func counter() func() int { n := 0 // captured by the closure, outlives counter() return func() int { n++ return n }…Когда выполняется
init()относительно импортов и переменных уровня пакета и почему не стоит класть в него настоящую работу?// lookup/lookup.gopackage lookup var a = b + 1 // dependency order, not source order: b is set first, so a is 3var b = 2…Чем отличается определение типа
type UserID stringот алиаса типаtype UserID = string?type UserID string // a new typetype Name = string // an alias: Name and string are the same type func (id UserID) Valid() bool { return strings.HasPrefix(string(id), "u_") } type Set[T comparable] = map[T]struct{} // Go 1.24: generic alias…Что изменилось в Go за последние несколько релизов и какие из этих изменений влияют на повседневный код?