Операторы объединяют операнды в выражения.
Expression = UnaryExpr | Expression binary_op Expression .
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
binary_op = "||" | "&&" | rel_op | add_op | mul_op .
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
add_op = "+" | "-" | "|" | "^" .
mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
Операторы сравнения будут обсуждаться в последующих постах. Для других бинарных операторов типы операндов должны быть идентичны, если только операция не включает сдвиги или нетипизированные константы.
За исключением операций сдвига, если один операнд является нетипизированной константой, а другой - нет, константа неявно преобразуется в тип другого операнда.
Правый операнд в выражении сдвига должен иметь целочисленный тип без знака или быть нетипизированной константой, представимой значением типа uint. Если левый операнд неконстантного выражения сдвига является нетипизированной константой, он сначала неявно преобразуется в тип, который он принял бы, если бы выражение сдвига было заменено только его левым операндом.
var s uint = 33
var i = 1<<s // 1 имеет тип int
var j int32 = 1<<s // 1 имеет тип int32; j == 0
var k = uint64(1<<s) // 1 имеет тип uint64; k == 1<<33
var m int = 1.0<<s // 1.0 имеет тип int; m == 0 если int являются 32-битными (32bits) в размере
var n = 1.0<<s == j // 1.0 имеет тип int32; n == true
var o = 1<<s == 2<<s // 1 и 2 имеют тип int; o == true если int являются 32-битными (32bits) в размере
var p = 1<<s == 1<<33 // недопустимо если int являются 32-битными (32bits) в размере: 1 имеет тип int, но 1<<33 переполняет int
var u = 1.0<<s // недопустимо: 1.0 имеет тип float64, не может сдвигаться
var u1 = 1.0<<s != 0 // недопустимо: 1.0 имеет тип float64, не может сдвигаться
var u2 = 1<<s != 1.0 // недопустимо: 1 имеет тип float64, не может сдвигаться
var v float32 = 1<<s // недопустимо: 1 имеет тип float32, не может сдвигаться
var w int64 = 1.0<<33 // 1.0<<33 является константным выражением сдвига
var x = a[1.0<<s] // 1.0 имеет тип int; x == a[0] если int являются 32-битными (32bits) в размере
var a = make([]byte, 1.0<<s) // 1.0 имеет тип int; len(a) == 0 если int являются 32-битными (32bits) в размере
Приоритет операторов
Унарные операторы имеют наивысший приоритет. Поскольку операторы ++ и -- формируют заявления (statements), а не выражения (expressions), они выходят за пределы иерархии операторов. Как следствие, заявление (statement) *p++ идентично (*p)++.
Существует пять уровней приоритета для бинарных операторов. Операторы умножения связывают сильнее всего, затем следуют операторы сложения, операторы сравнения, && (логическое И) и, наконец, || (логическое ИЛИ):
Приоритет Оператор
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
Бинарные операторы с одинаковым приоритетом ассоциируются слева направо. Например, x / y * z - это то же самое, что и (x / y) * z.
+x
23 + 3*x[i]
x <= f()
^a >> b
f() || g()
x == y+1 && <-chanPtr > 0
Читайте также:
- Спецификация Go: лексические элементы
- Спецификация Go: выражения (expressions) - операнды, квалифицированные идентификаторы
- Эффективный Go: функции
Комментариев нет:
Отправить комментарий