Привет! Поговорим про оператор ~
в Go, который многих сбивает с толку. Спойлер: это не одна, а целых две разные фичи в зависимости от контекста!
🤔 "Это что за знак такой?"
Видите тильду в Go коде? Не паникуйте! Это либо:
- Битовый переворот (чаще всего)
- Магия дженериков (в Go 1.18+)
🔄 Битовый NOT: переворачиваем биты
Представьте, что у вас есть число, а тильда просто переворачивает все его биты в двоичном представлении:
x := 5 // 00000101 в двоичной системе счисления
result := ^x // 11111010 в двоичной системе счисления
fmt.Println(result) // 250 для uint8, -6 для int8
Простая аналогия: как если бы вы инвертировали цвета в фотошопе — белое становится черным, черное белым.
Где полезно:
- Работа с битовыми масками
- Шифрование и низкоуровневые операции
- Оптимизация памяти
// Пример: проверка бита
const ReadPermission = 1 << 0 // 00000001
const WritePermission = 1 << 1 // 00000010
// Инвертируем маску чтобы получить все КРОМЕ определенных битов
allExceptWrite := ^WritePermission
🎯 Тильда в дженериках: aka "примерно такой тип"
С Go 1.18 тильда получила особое значение в дженериках:
// Ждет именно int
func StrictDouble[T int](x T) T { return x * 2 }
// Принимает любой тип с underlying type int
func FlexibleDouble[T ~int](x T) T { return x * 2 }
type MyInt int
func main() {
var num MyInt = 5
FlexibleDouble(num) // ✅ Работает!
StrictDouble(num) // ❌ Ошибка компиляции
}
Перевод на человеческий: ~int
значит "любой тип, который под капотом является int". Не дискриминирует алиасы :)
💡 Практические советы
-
Не путайте контексты:
- В выражениях:
^x
→ битовая операция - В дженериках:
[T ~int]
→ ограничение типа
- В выражениях:
Для битовых операций:
// Включение бита
flags |= mask
// Выключение бита
flags &^= mask // AND NOT
// Инверсия битов
flags = ^flags
-
В дженериках используйте
~
когда хотите принимать кастомные типы с нужным underlying type.
🚀 Итого
-
~
— это два разных оператора в одном флаконе - Битовый NOT: переворачиваем биты
- Approximation constraint: говорим дженерикам "принимай примерно такие типы"
Top comments (0)