Подтвердить что ты не робот

Используется ли "net/http" использование глобальных переменных в хорошей практике в голанге?

В пакете golang "net/http" используется глобальная переменная DefaultServeMux для регистрации обработчиков. Считается ли это хорошей практикой или даже игонией голанга? Это глобальная переменная?

Двумя основными причинами не использования глобальных переменных являются AFAIK 1), которые они добавляют к сложности и 2) являются проблематичными в параллельных программах.

Может быть, 1) не считается важным в этом случае, потому что разработчик может не использовать DefaultServerMux? Как насчет 2)? Являются ли глобальные переменные всегда безопасными для потоков /goroutine в Go? Тем не менее, я удивлен, что он использовался в стандартной библиотеке Go. Я никогда не видел такой практики в других языках/стандартных библиотеках.

4b9b3361

Ответ 1

Является ли это глобальной переменной?

Да. Переменная определена на корневом уровне, что делает ее глобальной по всему пакету.

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

Является ли это хорошей практикой или даже идиомой голанга?

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

Однако вы должны быть осторожны, когда собираетесь экспортировать переменные. Они должны быть готовы к параллельному доступу. Например, DefaultServeMux (или, лучше, базовый ServeMux), с использованием мьютекса, является потокобезопасным.

Являются ли глобальные переменные всегда безопасными для потоков /goroutine в Go?

Нет. Без правильной синхронизации (мьютекс, канал,...) все, к которому обращаются одновременно, является проблематичным и, безусловно, будет бить все по кусочкам.

Я никогда не видел такой практики в других языках/стандартных библиотеках.

Модуль Python logging, например, предоставляет функцию для восстановления корневого журнала, который может вызывать методы для настройки поведения ведения журнала. Это можно рассматривать как глобальный объект, поскольку он изменен и определен в модуле.

Ответ 2

Globvar в этом случае является безопасным и хорошим выбором, как аналог, например, в виде "log".

IOW, заявка 1 является такой же неопределенной, как она может быть получена, а требование 2 ограничено: когда-то/где-то истинно, в противном случае false == вообще не выполняется, хотя используется так же.