суббота, 8 июня 2019 г.

Спецификация Go: операторы, приоритет операторов

Операторы объединяют операнды в выражения.

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


Читайте также:


Комментариев нет:

Отправить комментарий