Программирование на языке Go: полезные советы. Часть 1 | OTUS
🔥 Что нужно, чтобы писать чистый код?
Курс «Архитектура и шаблоны проектирования». Спеццена для сдавших тест!
Подробнее

Курсы

Программирование
Подготовка к сертификации Oracle Java Programmer (OCAJP)
-8%
Алгоритмы и структуры данных
-12%
Backend-разработчик на PHP
-8%
Web-разработчик на Python
-11%
Архитектура и шаблоны проектирования
-14%
JavaScript Developer. Basic Интенсив «Оптимизация в Java»
-16%
Python Developer. Professional
-13%
Разработчик Golang
-17%
iOS Developer. Professional
-13%
Scala-разработчик
-21%
Java Developer. Professional
-12%
Разработчик Node.js
-15%
React.js Developer
-12%
Android Developer. Professional
-7%
Software Architect
-12%
Программист С MS SQL Server Developer Cloud Solution Architecture Reverse-Engineering. Professional CI/CD Agile Project Manager Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер-практикум по использованию и настройке GIT Symfony Framework Супер-интенсив "Tarantool"
Инфраструктура
PostgreSQL
-10%
Administrator Linux. Professional
-11%
Базы данных
-19%
Administrator Linux.Basic
-18%
Супер-интенсив «СУБД в высоконагруженных системах»
-18%
IoT-разработчик
-12%
Супер-интенсив "SQL для анализа данных"
-16%
Highload Architect
-9%
MS SQL Server Developer Безопасность Linux Cloud Solution Architecture Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Администратор Linux. Виртуализация и кластеризация Infrastructure as a code in Ansible Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Программирование на языке Go: полезные советы. Часть 1

Go_deep_10.9-5020-12a219.png

Предлагаем вашему вниманию подборку полезных советов, которые будут интересны разработчикам Go. При их использовании учитывайте, что далеко не все из этих рекомендаций можно применять в production, так как вы рискуете остаться без премии!

1. Как заставить пользователей пакетов использовать имена полей в составных литералах для структур?

Разработчики пакетов могут добавлять неэкспортируемые поля нулевого размера в определения структур. В этом случае компилятор не позволит использовать составные литералы с неименованными полями для создания экземпляров структур.

Пример:

// foo.go
package foo

type Config struct {
    _    [0]int
    Name string
    Size int
}
// main.go
package main

import "foo"

func main() {
    //_ = foo.Config{[0]int{}, "bar", 123} // error
    _ = foo.Config{Name: "bar", Size: 123} // compile ok
}

Не рекомендуется размещать неэкспортируемые поля нулевого размера в структуре последними, поскольку это может увеличить размер структуры.

2. Как создать структурный тип, который невозможно использовать в операциях сравнения?

В некоторых случаях необходимо запретить использование пользовательских структурных типов в качестве ключей отображения. Для этого достаточно добавить в структуру поле нулевого размера неэкспортируемого типа, для которого не реализована операция сравнения.

Пример:

package main

type T struct {
    dummy        [0]func()
    AnotherField int
}

var x map[T]int // ошибка компилятора: тип Т не может использоваться в качестве ключа отображения (invalid map key type T)

func main() {
    var a, b T
    _ = a == b // ошибка компилятора: недопустимая операция (invalid operation)
}

3. Не используйте оператор присваивания с взаимозависимыми выражениями

В текущей версии компилятора (Go 1.12) существует неопределенность порядка вычисления значений, присваиваемых одним оператором нескольким переменным с использованием взаимозависимых выражений. Таким образом, следует разделить оператор множественного присваивания значений на несколько присваиваний отдельных значений, если между выражениями, значения которых присваиваются, есть зависимости либо если вы не уверены, что таких зависимостей нет.

В некоторых неудачных вариантах присваивания отдельных значений также возможен неопределенный порядок вычисления выражений. Например, следующая программа выводит [7 0 9], [0 8 9] или [7 8 9] в зависимости от реализации компилятора.

package main

import "fmt"

var a = &[]int{1, 2, 3}
var i int
func f() int {
    i = 1
    a = &[]int{7, 8, 9}
    return 0
}

func main() {
    // Порядок вычисления a, i
    // и f() не определен.
    (*a)[i] = f()
    fmt.Println(*a)
}

Иными словами, результатом вызова функции при присвоении значения может стать изменение значений других выражений в этом же операторе. Более подробную информацию о порядке вычисления и инициализации значений см. в этой статье.

4. Варианты реализации оператора for i in 0..N, используемого в других языках

Для имитации такого цикла можно осуществить перебор массива с элементами нулевого размера или использовать пустой (nil) указатель на массив.

Пример:

package main

import "fmt"

func main() {
    const N = 5

    for i := range [N]struct{}{} {
        fmt.Println(i)
    }
    for i := range [N][0]int{} {
        fmt.Println(i)
    }
    for i := range (*[N]int)(nil) {
        fmt.Println(i)
    }
}

5. Значения некоторых типов стандартных пакетов не предназначены для копирования

В частности, не рекомендуется выполнять копирование значений типов bytes.Buffer и strings.Builder, а также типов пакета sync (в некоторых особых случаях безопасное копирование значений данных типов возможно, но лучше их не копировать).

Реализация типа strings.Builder отслеживает некорректные копии значений этого типа. При обнаружении такой копии в процессе исполнения программы возникает состояние «паники» (panic).

Пример:

package main

import "strings"

func main() {
    var b strings.Builder
    b.WriteString("hello ")
    var b2 = b
    b2.WriteString("world!") // паника
}

При копировании значений типов стандартного пакета sync команда go vet из комплекта Go SDK выдаст соответствующее предупреждение.

// demo.go
package demo

import "sync"

func f(m sync.Mutex) { // warning
    m.Lock()
    defer m.Unlock()
    // do something ...
}
$ go vet demo.go
./demo.go:5: f passes lock by value: sync.Mutex

Попытка копирования значений bytes.Buffer не будет обнаружена ни в процессе выполнения, ни командой go vet. Так что, будьте внимательны и не копируйте их.

Это первый блок советов по Go. Продолжение следует, следите за новостями!

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться