Обновить
8

Программист

Отправить сообщение
Длинна неинициализированного массива — 0.

Под массивом наверно имеется в виду slice.
Из того же букваря go.dev/tour/moretypes/12:
The zero value of a slice is nil.
A nil slice has a length and capacity of 0 and has no underlying array.
Возможно совпадение, но сегодня резко упала скорость на скачивание релизов с github. Мобильный оператор (мтc), ноутбучный тариф. Например, файл https://github.com/docker/compose/releases/download/1.28.5/docker-compose-Linux-x86_64 качает со скоростью 13КБ/сек что в браузере, что через wget. Tor Browser качает быстро.
Не вникал в код, но мне кажется, вам бы подошли стандартные Ticker и Timer. При этом это были бы локальные объекты для вашей горутины, и не нужно было бы использовать глобальную синхронизируемую коллекцию таймеров.
Для устранения «недочетов» оформления кода и вообще на этапе ознакомления с языком можно использовать возможности IDE — например, GoLand (хотя он платный, но есть EAP/trial).
В дополнение к проверкам IDE есть линтеры. github.com/golangci/golangci-lint включает большой их набор, но по-умолчанию включены не все.
«Самопальный» timer возможно тоже стоит заменить на context.WitdDeadline() или context.WithTimeout()
Если программа завершает работу, то какими-то завершающими действиями можно пренебречь, если они не влияют на результат. Например, csv writer лучше всё-таки зафлашить, а соответствующий открытый файл закрыть. Но конкретно с сигналами я никогда не видел код, который бы явно вызывал Stop имено для того, чтобы устранить утечку, потому что все равно программа тут же закрывается.

С контекстом было бы примерно так:
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)

	go func() {
		<-signals
		fmt.Println("cancel")
		cancel()
	}()

	done := make(chan struct{})

	go func() {
		for {
			select {
			case <-ctx.Done():
				close(done)
				return
			}
		}
	}()

	<-done
	fmt.Println("exit")
}
Запись в «занулённый» канал из ранее запущенной goroutine (завешивает «навечно» функцию со всеми объектами).

Я бы порекомендовал книжку Concurrency in Go.
  1. Не совсем понятно — у вас приведенная горутина (To complete report processing even after return on timeout) вызывается в каком-то цикле, что утечка накапливается?
  2. Обычно после «получения» сигнала программа так или иначе завершается, поэтому примеры кода в документации приведены на этот самый простой распространенный кейс.
  3. Как правило, сигналы «ловят» на уровне main или близком к нему — в функцию обычно передают и работают с контекстом (context.Context).
  4. Вместо done <- struct{}{} в большинстве случаем можно и принято использовать close(done).
www.python.org/downloads/release/python-390
This is the first version of Python to default to the 64-bit installer on Windows. The installer now also actively disallows installation on Windows 7. Python 3.9 is incompatible with this unsupported version of Windows.
С 1 июля 2020 г. (через 4 дня) режим вводится уже во многих регионах.
Выводите в рублях или долларах?
В База знаний по налогу на профессиональный доход есть пара вопросов на эту тему:

ВОПРОС: Каким образом сформировать чек, если оплата услуг произведена в иностранной валюте?

ОТВЕТ: Если оплата поступила в иностранной валюте, сумму нужно пересчитать по курсу Центрального банка Российской Федерации на день получения. Этот порядок предусмотрен Налоговым кодексом. В чеке необходимо указывать сумму в рублях РФ.

ВОПРОС: При получении оплаты от реализации товаров (работ, услуг, имущественных прав) в иностранной валюте, в какой момент нужно создавать выручку в приложении, когда она приходит на транзитный счет или, когда она приходит на расчетный счет после валютного контроля?

ОТВЕТ: Получение доходов от реализации товаров (работ, услуг, имущественных прав) признается дата поступления таких денежных средств на счета налогоплательщика налога на профессиональный доход, то есть на расчетный счет после валютного контроля. При формировании чека сумма расчетов указывается эквивалентной сумме в рублях по курсу Центрального банка Российской Федерации на дату поступления таких денежных средств на счета «самозанятого» налогоплательщика.

Обращаем внимание, что при денежных расчетах в безналичном порядке чек должен быть сформирован и передан в электронной форме или на бумажном носителе покупателю (заказчику) не позднее 9-го числа месяца, следующего за налоговым периодом, в котором произведены расчеты, путем направления чека покупателю (заказчику) на абонентский номер или адрес электронной почты, представленные покупателем (заказчиком), или путем обеспечения покупателю (заказчику) возможности в момент формирования чека в месте продажи считать компьютерным устройством (мобильным телефоном, смартфоном или компьютером, включая планшетный компьютер) QR-код, содержащийся на чеке.
1. Я про Go.
2. Я имею в виду, что отсутствие явного null конечно помогает избежать части ошибок, но если разработчик забыл где-то поменять дефолтное значение инициализации (IDE сгенерировала 0 по умолчанию, например, для поля обязательного идентификатора создаваемой структуры), то компилятор на это внимания не обратит.
3. По вашей ссылке открывается что-то не то, мне кажется.
В Go вам надо помнить эту особенность и при добавлении в «чужой» map (что на практике и не так часто встречается) проверять на nil. В других языках с nullable-типами проверять нужно все операции.
Я не спорю, что система типов в Rust более развита.
А что вы будете делать внутри «страховочной» проверки на nil, как будете обрабатывать эту ситуацию, которой быть вроде как быть не должно?
Функция иногда может возвращать и пустые значения других типов (строк, чисел), потому что разработчик забыл заполнить поля или случайно оставил сгенерированные заглушки. И не nil, но толку от них тоже нет, и проблемы будут только в runtime (может быть в Rust и можно реализовать compiletime-проверки с помощью макросов, например — я пока до них не добрался).
1. Автор функции вполне может вернуть nil-мапу (не говоря уж о nil-слайсе). Это не его проблема, что вы хотите потом туда что-то добавлять (если это явно не продиктовано семантикой функции), а остальные операции с nil-мапой и так работают, так что это вполне легальный результат. Документацию просмотреть да, придется, но вы наверно и так это делаете. При отсутствии явных указаний в документации загромождать «страховочными» проверками результата на nil по мне не стоит, если только не поймали панику во время выполнения/прогоне тестов.
2. Разница есть, но она не бесплатна — сложность языка, время компиляции, кривая обучения, уровень поддержки в IDE и т.д. Любой компилятор (линтер, ...) имеет баги для некоторых исключительных/специфических ситуаций.
Почему в Go то нельзя, чем он отличается в данном кейсе от других современных языков с null? Да, нет generic-ов, но можно добавить структуру вручную:
type EventResult struct {
	Event *Event
	Err   error
}

Другое дело, что в обычных функциях такой подход не является идиоматичным, но например в каналах такие структуры используются для проталкивания ошибок наверх потребителям.
1. С т.з. вызывающего кода — если функция вернула nil, nil, значит ошибки нет, а первый nil — это вполне нормальный результат (например, slice или map) с т.з. автора функции (в неочевидных случаях автор должен уточнить в документирующем комментарии к функции).
2. Игнорирование ошибок можно проконтролировать с помощью линтера errcheck (от также включен в набор линтеров golangci-lint). Что-то может подсказать и IDE (в частности, GoLand ругается 'result' may have 'nil' or other unexpected value as its corresponding error variable may be not 'nil')
Без примера кода непонятно в чем именно проблема, но скорее всего надо использовать select вместе с time.After (time.NewTimer) — в простейшем случае что-то типа:
select {
case <- time.After(timeout):
	println("timeout")
case <- events:
	println("event")
}

В Go by Example (рекомендуется просмотреть в дополнение к другим ресурсам) есть соответствующий пример.
1. Вместо обратного слэша должен быть прямой и имя файла в коде теста должно полностью совпадать с именем в файловой системе, т.е. например путь test_files\utf8-wbom.txt должен быть test_files/utf8-wBOM.txt.
Надо использовать функцию filepath.Join() — это решит проблему со слэшами.
Небольшие файлы для тестов можно затащить в исходники — большие (или например картинки) я бы не стал.
2. Наверно вы невнимательно посмотрели — golangci-lint-1.22.2-windows-amd64.zip
3. Я вообще не припомню, чтобы видел в чьем-то коде такую проверку на nil с помощью reflect — такая проверка меня бы как минимум насторожила, почему сделано так заморочено. Обычной проверки на nil было бы достаточно, тем более что на практике лично я вообще ни разу не сталкивался с этим «оттенком» Go. В Go принято по-возможности обрабатывать nil случаи без возврата ошибки — например, в вашем коде можно было бы вернуть кодировку ASCII без ошибки «input reader is nil», т.е трактовать nil ридер и ридер без данных одинаково. Проверку на EOF лучше писать как err != io.EOF
Взглянул на исходники — навскидку несколько замечаний:

В тестах windows-пути прошиты с обратным слэшем и регистронезависимые — на Linux тесты падают. Например, «test_files\\utf8-wbom.txt»

C этой библиотечкой тесты будут выглядеть попроще.

Линтеры выдают несколько предупреждений — орфография, неиспользуемый код, необработанные ошибки.

Проверять на nil конкретно в том месте наверно вообще не стоит — в вашем случае nil можно рассматривать как нарушение контракта, пусть паникует, а проверка на nil возлагается на клиентов метода. Например, после проверки вы используете библиотечный метод bufio.NewReader( r ).Peek(ReadBufSize), который тоже не проверяет на nil и паникует.
Тут перечислены необходимые зависимости/требования для разных операционных систем. Даже для Windows может потребоваться установка дополнительных пакетов.

Информация

В рейтинге
6 591-й
Откуда
Ижевск, Удмуртия, Россия
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Фулстек разработчик