Какие максимальные значения int и uint в Go?
Поскольку целочисленные типы используют двоичную арифметику, можно вычислить их предельные значения подобных образом:
const MaxUint = ^uint(0)
const MinUint = 0
const MaxInt = int(MaxUint >> 1)
const MinInt = -MaxInt - 1
А вот полный перечень целочисленных типов и их диапазонов:
- uint8 : 0 to 255
- uint16 : 0 to 65 535
- uint32 : 0 to 4 294 967 295
- uint64 : 0 to 18 446 744 073 709 551 615
- int8 : -128 to 127
- int16 : -32 768 to 3 2767
- int32 : -2 147 483 648 to 2147 483 647
- int64 : -9 223 372 036 854 775 808 to 9 223 372 036 854 775 807
Ещё один способ сделать это:
func printMinMaxValue() {
// integer max
fmt.Printf("max int64 = %+v\n", math.MaxInt64)
fmt.Printf("max int32 = %+v\n", math.MaxInt32)
fmt.Printf("max int16 = %+v\n", math.MaxInt16)
// integer min
fmt.Printf("min int64 = %+v\n", math.MinInt64)
fmt.Printf("min int32 = %+v\n", math.MinInt32)
fmt.Printf("max flloat64= %+v\n", math.MaxFloat64)
fmt.Printf("max float32= %+v\n", math.MaxFloat32)
// etc you can see more int the `math`package
}
max int64 = 9223372036854775807
max int32 = 2147483647
max int16 = 32767
min int64 = -9223372036854775808
min int32 = -2147483648
max flloat64= 1.7976931348623157e+308
max float32= 3.4028234663852886e+38
fatal error: concurrent map read and map write
Это очень неприятная ошибка, так как отловить её на этапе разработки или тестирования достаточно сложно, а вот в продакшене при высокой нагрузке она моментально зафаталит приложение. Суть такова: несколько потоков исполнения (горутин) одновременно хотят прочитать и записать данные в переменную с типом map.
Go отлавливает подобную ситуацию в runtime и выбрасывает фатальную ошибку. Иначе конкурентный доступ к одной переменной может привести к несогласованности этих данных. Решается достаточно просто: нужно установить блокировку перед тем как работать с данной переменной. По сути нужно сделать работу с этим значением однопоточным с помощью реализации mutex из пакета sync:
var mutex sync.Mutex
func request() {
mutex.Lock()
cntRequests["something"]++
mutex.Unlock()
}
К сожалению, подобные ситуации невозможно отловить с помощью режима обнаружения race conditions.
Как в Go превратить массив байтов в строку
Самый простой способ:
string(data[:])
Можно также указать необходимый диапазон байт для конвертации:
string(data[:150])
Однако, при использовании данного способа в отладчике через evaluate будет конвертирована не вся строка, а только её часть.
Как в Go Lang вывести строку по указателю?
Допустим, какая-либо функция возвращает не строку, а указатель на строку. И при попытке распечатать значение вместо желаемой строки получается что-то вроде:
0xc00021e160
Чтобы вывести содержимое строки, нужно при выводе также указывать указатель на переменную:
fmt.Fprint(httpResponse, *responseData)
Runtime error: assignment to entry in nil map
Такая ошибка происходит во время попытки сохранения значения в не проинициализированный map. При этом объявление переменной инициализацией не считается:
var myMap map[string] uint64
Нужно дополнительно вызывать:
myMap = make(map[string] uint64)
Как в Go обрабатывать ошибки в стиле try-catch?
Для тех кто привык работать с языками с поддержкой исключений модель ошибок в Go может показаться неудобной. Однако с помощью несложных способом можно и в Go работать с ошибками как с исключениями:
data, e := exec()
if nil != e {
switch e.(type) {
case NotFoundError:
return nil, e
case FatalError:
return nil, e
default:
log.Println("Error: " + e.Error())
}
}
Как в Go создавать свои типы ошибок?
Ошибкой в Go считается любая структура соответствующая интерфейсу:
type error interface {
Error() string
}
Например:
type FatalError struct {
error error
}
func (err FatalError) Error() string {
return err.error.Error()
}
Использовать можно так:
if err := json.Unmarshal(body, &data); err != nil {
return nil, FatalError{error: err}
}
Как в Go создавать типы для функций?
Очень удобно выделить сигнатуру функции в тип и использовать его для улучшения читаемости и упрощения модификации кода. Например:
type execFunc = func(client Client) (*string, error)
Использовать можно так:
var exec execFunc
exec = func(client Client) (*string, error) {
return webMediaInfo(media, *client.Client)
}