Привет, ребята!

Делюсь опытом, урок #1.

Язык для примеров  - Golang.

*---------------------------------------------------------------------------------*
Контекстный словарик:

Легальный код, код — авторский код, без внешнего вмешательства;

Переменная — именованная область памяти, доступная для редактирования (изменения) легальным кодом данной программы;

Константа — не редактируемая легальным кодом именованная область памяти;

Объект, имя — общее указание на Переменные и Константы.

*---------------------------------------------------------------------------------*
Итак, правила:
*---------------------------------------------------------------------------------*
имя состоит из нескольких слов слитно и начинается с маленькой буквы. Каждое последующее слово этого имени с большой:

var (
sendResultBytes []byte
)

*---------------------------------------------------------------------------------*
имя должно максимально ёмко обозначить назначение и смысл объекта настолько, чтобы не пришлось комментировать дополнительно, на сколько это получится с сохранением читаемости кода, а в конце имени указываю тип этого объекта:

   send — отправить сообщение
   Result — собираемый в одной переменной результат вычислений / сбора данных
   Bytes — тип переменной []byte / байтовый срез / слайс

//  Определяем константы:
const (
       apiUx  byte  = 1
       apiUxPrintLogText  byte  = 1
)
var (
       textHelloWorld  []byte  =  []bytes("Hello world!")
)

// Выделяем новый участок памяти под формирование строки:
sendResultBytes = nil

// Первыми идут API-команды:
sendResultBytes = append(sendResultBytes,  apiUi,  apiUiPrintLogText)

// Добавляем само сообщение для вывода в логирующий терминал:
sendResultBytes = append(sendResultBytes,  textHelloWorld...)

// Отправляем в канал рассылки:
chSendMsgToFront <- sendResultBytes

*---------------------------------------------------------------------------------*
+ у объектов — перечней/списков должны быть общие признаки в именах:
errorPage404
errorUnknown
errorNameLenMustBe256max
errorNameLenMustBe8min

*---------------------------------------------------------------------------------*
+ если нужно присвоить конкретное значение переменной, то удобнее использовать указание на константу:
// можно сделать так:
bufferLoginLength = 256
bufferPassLength = 256


// удобнее сделать так:
const (
   maxBufferLength = 256
)
bufferLoginLength = maxBufferLength
bufferPassLength = maxBufferLength

Во втором варианте не придётся по всему коду бегать искать все места упоминания размерности в 256, достаточно будет изменить константу.
Это правило касается даже тех случаев, когда значение будет равно «1».
И количество констант, равных «1», может быть несколько, но с разными именами.

*---------------------------------------------------------------------------------*
+ наличие и использование констант помогает осознавать, что при чтении значения из неё не придётся блокировать мьютекс, так как не будет возникать ситуации с одновременным обращением на чтение и запись из разных потоков выполнения кода.

*---------------------------------------------------------------------------------*
+ начинать имя с маленькой буквы нужно для того, чтобы отличать переменные родительского класса от дочернего, так же добавляем внутренний мьютекс структуре и используем табуляцию для красоты и читаемости:

// назначаем структуру родительского типа:
type broadcastList struct {
       Mu            sync.Mutex
       Address   string
       Name       string
       UniqID    uint64
}

//  назначаем переменную родительского типа:
parrentBroadcast := new(broadcastList)

//   Блокируем мьютекс с Tab-отступом для удобства визуального восприятия кода:
       parrentBroadcast.Mu.Lock()

//  присваиваем значения переменным дочернего типа:
parrentBroadcast.Address = "@Mars planet"
parrentBroadcast.Name = "Elon Musk"
parrentBroadcast.UniqID = 1

//    Освобождаем мьютекс:
       parrentBroadcast.Mu.Unlock()

*---------------------------------------------------------------------------------*
+  для тяжёлых / долгих операций над распределёнными значениями, выгоднее задействовать дополнительные переменные, если дело не касается критичности в актуальности значений и расход дополнительной памяти не приведёт к переполнению.

Например, для вывода в терминал может использоваться тяжёлая конструкция log.Printf, которая в данном примере не имеет критичности к точности распределённых данных на момент вывода, и её не обязательно исполнять в режиме блокировки:
       mu.Lock()
a := unixTimeScaleUint64
       mu.Unlock()
log.Printf("8755 unix = %d", a)

Таким образом, распределённая переменная unixTimeScaleUint64 как можно раньше становится доступной для других потоков, в то время когда копия её значения используется для вывода в терминал долгой инструкцией.

Обратите внимание на цифру 8755, указывающую на номер строки текстового кода — это дополнительное удобство для трассировки программы в режиме программирования/отладки, чтобы было понятно в какой момент срабатывает вывод в терминал.

*---------------------------------------------------------------------------------*
+ Для быстрого возврата к месту последнего редактирования кода (в рамках текущей сессии), удобно использовать комбинацию сочетаний клавиш CTRL+Z  и  сразу CTRL+Y.

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

*---------------------------------------------------------------------------------*
+ Если что упустил из виду ещё, то дополнять буду в последующих уроках.

Обсуждать не получится, так как всего один коммент в сутки доступен. Либо пишите в л.с., если что подсказать смогу.

Спасибо за внимание!

Сергей Попов (Socket Language)

Комментарии (4)


  1. Starl1ght
    21.11.2022 02:11
    +3

    Чего?


  1. skymal4ik
    21.11.2022 02:21

    Определённо не хватает тега #ненормальноепрограммирование, объяснения смысла это с виду бесполезной формализации и этого кода…

    Про оформление молчу, с первым абзацем бы справиться :))


  1. mSnus
    21.11.2022 02:32

    А Хабр-то всё ещё торт! Некоторые вещи неизменны.


  1. Electrohedgehog
    21.11.2022 04:02

    Настоятельно рекомендую автору перед написанием следующей статьи принять галоперидола.

    Для тех недостаточно опытных читателей, кто решит, что автор написал что-то умное, но непонятное, хочу отметить, что помимо внутренней противоречивости текста он противоречит всем известным мне принципам именования переменных.