вторник, 21 мая 2019 г.

Спецификация Go: переменные (variables)

Переменная - это место хранения для значения. Набор допустимых значений определяется типом переменной.

Объявление переменной или, для параметров и результатов функции, подпись объявления функции или литерала функции резервирует хранилище для именованной переменной. Вызов встроенной функции new или получение адреса составного литерала выделяет память для переменной во время выполнения. На такую анонимную переменную ссылаются через (возможно, неявный) указатель косвенности (pointer indirection).

Структурированные переменные типа array, slice и struct имеют элементы и поля, которые могут быть адресованы индивидуально. Каждый такой элемент действует как переменная.

Статический тип (или просто тип) переменной - это тип, указанный в ее объявлении, тип, указанный в new вызове или составном литерале, или тип элемента структурированной переменной. Переменные типа интерфейса также имеют отдельный динамический тип, который является конкретным типом значения, назначенного переменной во время выполнения (если только это значение не является предварительно объявленным идентификатором nil, который не имеет типа). Динамический тип может изменяться во время выполнения, но значения, хранящиеся в интерфейсных переменных, всегда можно назначить статическому типу переменной.

var x interface{}  // x это nil и имеет статический тип interface{}
var v *T           // v имеет значение nil, статический тип *T
x = 42             // x имеет значение 42 и динамический тип int
x = v              // x имеет значение (*T)(nil) и динамический тип *T

Значение переменной извлекается путем обращения к переменной в выражении; это самое последнее значение, присвоенное переменной. Если переменной еще не присвоено значение, ее значением является нулевое значение для ее типа.


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


Спецификация Go: константы

Существуют логические константы, рунные константы, целочисленные константы, константы с плавающей точкой, комплексные константы и строковые константы. Рунические, целочисленные, с плавающей точкой и комплексные константы вместе называются числовыми константами.

Значение константы представлено руническим, целым, плавающим, мнимым или строковым литералом, идентификатором, обозначающим константу, константным выражением, преобразованием с результатом, который является константой, или значением результата некоторых встроенных функций, таких как unsafe.Sizeof применяемой к любому значению, cap или len применяются к некоторым выражениям, real и imag применяются к комплексной константе, а complex применяется к числовым константам. Значения логической истинности представлены заранее объявленными константами true и false. Предварительно объявленный идентификатор йота (iota) обозначает целочисленную константу.

В общем, сложные константы являются формой константного выражения и обсуждаются в этом разделе.

Числовые константы представляют собой точные значения произвольной точности и не переполняются. Следовательно, нет констант, обозначающих IEEE-754 отрицательный ноль, бесконечность и не числовые (not-a-number) значения.

Константы могут быть типизированными или нетипизированными. Литеральные константы, true, false, йота и некоторые константные выражения, содержащие только нетипизированные константные операнды, являются нетипизированными.

Константе может быть дан тип явно посредством объявления или преобразования константы, или неявно, когда используется в объявлении переменной или присваивании или как операнд в выражении. Это ошибка, если постоянное значение не может быть представлено как значение соответствующего типа.

Нетипизированная константа имеет тип по умолчанию, который является типом, в который константа неявно преобразуется в контекстах, где требуется типизированное значение, например, в коротком объявлении переменной, таком как i := 0, где нет явного типа. Типом по умолчанию нетипизированной константы является bool, rune, int, float64, complex128 или string соответственно, в зависимости от того, является ли она логической, рунической, целой, с плавающей точкой, комплексной или строковой константой.

Ограничение реализации: хотя числовые константы имеют произвольную точность в языке, компилятор может реализовать их, используя внутреннее представление с ограниченной точностью. Тем не менее, каждая реализация должна:

  • Представлять целочисленные константы с как минимум 256 битами.
  • Представлять константы с плавающей точкой, включая части комплексной константы, с мантиссой не менее 256 бит и двоичным показателем со знаком не менее 16 бит.
  • Выдавать ошибку, если не может точно представить целочисленную константу.
  • Выдавать ошибку, если не может представить плавающую точку или комплексную константу из-за переполнения.
  • Округлять до ближайшей представимой константы, если не может представить с плавающей точкой или комплексную константу из-за ограничений по точности.

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


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


понедельник, 20 мая 2019 г.

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

Строковые литералы (String literals)

Строковый литерал представляет собой строковую константу, полученную в результате объединения последовательности символов. Существует две формы: необработанные строковые литералы (raw string literals) и интерпретируемые строковые литералы (interpreted string literals).

Необработанные строковые литералы - это символьные последовательности между обратными кавычками, как в `foo`. В кавычках может появляться любой символ, кроме обратной кавычки. Значение необработанного строкового литерала - это строка, состоящая из неинтерпретированных (неявно кодированных в UTF-8) символов между кавычками; в частности, обратная косая черта не имеет специального значения, и строка может содержать символы новой строки. Символы возврата каретки ('\r') внутри необработанных строковых литералов отбрасываются из необработанного строкового значения.

Интерпретируемые строковые литералы являются символьными последовательностями между двойными кавычками, как в "bar". В кавычках может появляться любой символ, кроме символа новой строки (newline) и неэкранированной двойной кавычки. Текст между кавычками формирует значение литерала, с экранированием обратной косой черты, интерпретируемым так же как в литералах рун (за исключением того, что \' недопустимо, а \" является законным), с теми же ограничениями. Трехзначный восьмеричный (\nnn) и двузначные шестнадцатеричные (\xnn) escape-символы представляют отдельные байты результирующей строки, все другие escape-последовательности представляют (возможно, многобайтовую) кодировку UTF-8 отдельных символов. Таким образом, внутри строкового литерала \377 и \xFF представляют один байт значения 0xFF = 255, тогда как ÿ, \u00FF, \U000000FF и \xc3\xbf представляют два байта 0xc3 0xbf кодировки UTF-8 символа U+00FF (символ ÿ).

string_lit             = raw_string_lit | interpreted_string_lit .
raw_string_lit         = "`" { unicode_char | newline } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .

Примеры:

`abc`                // то же самое что и "abc"
`\n
\n`                  // то же самое что и "\\n\n\\n"
"\n"
"\""                 // то же самое что и `"`
"Hello, world!\n"
"日本語"
"\u65e5本\U00008a9e"
"\xff\u00FF"
"\uD800"             // недопустимо: суррогатная половина (surrogate half)
"\U00110000"         // недопустимо: невалидная Unicode кодовая точка

Следующие примеры представляют одну и ту же строку:

"日本語"                                 // UTF-8 текст ввода
`日本語`                                 // UTF-8 текст ввода как необработанный литерал
"\u65e5\u672c\u8a9e"                    // явные Unicode кодовые точки
"\U000065e5\U0000672c\U00008a9e"        // явные Unicode кодовые точки
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // явные UTF-8 байты

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


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


Спецификация Go: литералы рун

Литералы рун (Rune literals)

Литерал руны представляет собой константу руны, целочисленное значение, идентифицирующее кодовую точку Unicode. Литерал руны выражается в виде одного или нескольких символов, заключенных в одинарные кавычки, например, 'x' или '\n'. В кавычках может появляться любой символ, кроме новой строки и неэкранированной одинарной кавычки. Символ в кавычках представляет значение Unicode самого символа, а многосимвольные последовательности, начинающиеся с обратной косой черты, кодируют значения в различных форматах.

Самая простая форма представляет один символ в кавычках; поскольку исходный текст Go представляет собой символы Unicode, закодированные в UTF-8, несколько байтов в кодировке UTF-8 могут представлять одно целочисленное значение. Например, литерал 'a' содержит один байт, представляющий литерал a, Unicode U+0061, значение 0x61, в то время как 'ä' содержит два байта (0xc3 0xa4), представляющий литерал a-dieresis, U+00E4, значение 0xe4.

Несколько экранов с обратной косой чертой позволяют кодировать произвольные значения в виде текста ASCII. Существует четыре способа представления целочисленного значения в виде числовой константы: \x, за которой следуют ровно две шестнадцатеричные цифры; \u, за которой следуют ровно четыре шестнадцатеричные цифры; \U, за которой следуют ровно восемь шестнадцатеричных цифр и простой обратный слеш \, за которыми следуют ровно три восьмеричных знака. В каждом случае значение литерала - это значение, представленное цифрами в соответствующей базе.

Хотя все эти представления приводят к целому числу, они имеют разные допустимые диапазоны. Восьмеричные экранирования должны представлять значение от 0 до 255 включительно. Шестнадцатеричные экранирования удовлетворяют этому условию по построению. Экранирующие символы \u и \U представляют кодовые точки Unicode, поэтому в них некоторые значения недопустимы, в частности значения выше 0x10FFFF и суррогатные половины.

После обратной косой черты некоторые односимвольные экранированные символы представляют собой специальные значения:

\a   U+0007 alert or bell
\b   U+0008 backspace (пробел)
\f   U+000C form feed (символ конца страницы)
\n   U+000A line feed or newline (символ возврата строки)
\r   U+000D carriage return (символ возврата каретки)
\t   U+0009 horizontal tab (горизонтальный таб)
\v   U+000b vertical tab (вертикальный таб)
\\   U+005c backslash (обратный слеш)
\'   U+0027 single quote  (одинарная кавычка, валидный экран только внутри литералов рун)
\"   U+0022 double quote  (двойная кавычка, валидный экран только внутри строковых литералов)

Все остальные последовательности, начинающиеся с обратной косой черты, недопустимы внутри литералов рун.

rune_lit         = "'" ( unicode_value | byte_value ) "'" .
unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
byte_value       = octal_byte_value | hex_byte_value .
octal_byte_value = `\` octal_digit octal_digit octal_digit .
hex_byte_value   = `\` "x" hex_digit hex_digit .
little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
                           hex_digit hex_digit hex_digit hex_digit .
escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .

Примеры:

'a'
'ä'
'本'
'\t'
'\000'
'\007'
'\377'
'\x07'
'\xff'
'\u12e4'
'\U00101234'
'\''         // литерал руны, содуржащий символ одинарной кавычки
'aa'         // недопустимо: слишком много символов
'\xa'        // недопустимо: слишком мало шестнадцатеричных цифр
'\0'         // недопустимо: слишком мало восьмеричных цифр
'\uDFFF'     // недопустимо: суррогатная половина
'\U00110000' // недопустимо: невалидная Unicode кодовая точка


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


Спецификация Go: литералы

Целочисленные литералы (Integer literals)

Целочисленный литерал - это последовательность цифр, представляющая целочисленную константу. Необязательный префикс устанавливает недесятичное основание: 0 для восьмеричного, 0x или 0X для шестнадцатеричного. В шестнадцатеричных литералах буквы a-f и A-F представляют значения от 10 до 15.

int_lit     = decimal_lit | octal_lit | hex_lit .
decimal_lit = ( "1" … "9" ) { decimal_digit } .
octal_lit   = "0" { octal_digit } .
hex_lit     = "0" ( "x" | "X" ) hex_digit { hex_digit } .

Примеры:

42
0600
0xBadFace
170141183460469231731687303715884105727

Литералы с плавающей точкой (Floating-point literals)

Литерал с плавающей точкой является десятичным представлением константы с плавающей точкой. Он имеет целочисленную часть, десятичную точку, дробную часть и экспоненту. Целая и дробная части содержат десятичные цифры; часть экспоненты представляет собой e или E, за которыми следует десятичный показатель степени с необязательной подписью. Одна из целочисленной части или дробной части может быть исключена; одна из десятичной точки или показатель степени могут быть исключены.

float_lit = decimals "." [ decimals ] [ exponent ] |
            decimals exponent |
            "." decimals [ exponent ] .
decimals  = decimal_digit { decimal_digit } .
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .

Примеры:

0.
72.40
072.40  // == 72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5

Мнимые литералы (Imaginary literals)

Мнимый литерал - это десятичное представление мнимой части комплексной константы. Он состоит из литерального или десятичного целого числа с плавающей точкой, за которым следует строчная буква i.

imaginary_lit = (decimals | float_lit) "i" .

Примеры:

0i
011i  // == 11i
0.i
2.71828i
1.e+0i
6.67428e-11i
1E6i
.25i
.12345E+5i

Примечание: комплексное число (что такое мнимая часть, Википедия)


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


воскресенье, 19 мая 2019 г.

Спецификация Go: лексические элементы

Комментарии

Комментарии служат программной документацией. Есть две формы комментариев в Go:

  • Строчные комментарии (Line comments) начинаются с последовательности символов // и заканчиваются в конце строки.

  • Общие комментарии (General comments) начинаются с последовательности символов /* и заканчиваются первой встреченной следом последовательностью символов */.

Комментарий не может начинаться внутри рунного или строкового литерала или внутри комментария. Общий комментарий (/* */), не содержащий новых строк, действует как пробел. Любой другой комментарий действует как перевод строки.

Токены (Tokens)

Токены образуют словарь языка Go. Существует четыре класса токенов: идентификаторы (identifier), ключевые слова (keyword), операторы (operator) и знаки препинания (punctuation), литералы (literal). Пустое место, образованное из пробелов (U+0020), горизонтальных табуляций (U+0009), возвратов каретки (U+000D) и символа перевода строки (newline) (U+000A), игнорируется, за исключением того, что оно разделяет токены, которые в противном случае объединялись бы в один токен. Кроме того, новая строка (newline) или конец файла может инициировать вставку точки с запятой. Во время разделения входных данных на токены, следующим отдельным токеном считается самая длинная последовательность символов, которые образуют валидный токен.

Точки с запятой

Формальная грамматика использует точки с запятой ";" как терминаторы в ряде производств. Go программы могут опустить большинство этих точек с запятой, используя следующие два правила:

  1. Когда входные данные разбиты на токены, точка с запятой автоматически вставляется в поток токенов сразу после последнего токена строки, если этот токен
    • идентификатор
    • целое число (integer), число с плавающей точкой (floating-point), мнимый (imaginary), рунический (rune) или строковый (string) литерал
    • одно из ключевых слов: break, continue, fallthrough, или return
    • один из операторов и знаков препинания ++, -, ), ] или }
  2. Чтобы разрешить сложным операторам занимать одну строку, точка с запятой может быть опущена перед закрывающими ")" или "}".

Идентификаторы

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

identifier = letter { letter | unicode_digit } .

a
_x9
ThisVariableIsExported
αβ

Некоторые идентификаторы предопределены.

Ключевые слова

Следующие ключевые слова зарезервированы и не могут быть использованы в качестве идентификаторов:

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

Операторы и знаки пунктуации

Следующие последовательности символов представляют операторы (включая операторы присвоения) и знаки пунктуации:

+    &     +=    &=     &&    ==    !=    (    )
-    |     -=    |=     ||    <     <=    [    ]
*    ^     *=    ^=     <-    >     >=    {    }
/    <<    /=    <<=    ++    =     :=    ,    ;
%    >>    %=    >>=    --    !     ...   .    :
     &^          &^=


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


суббота, 4 мая 2019 г.

Спецификация Go: представление исходного кода

Исходный код в Go - это Unicode текст, в кодировке UTF-8. Текст не канонизирован, поэтому одна акцентированная кодовая точка отличается от того же символа, сконструированного из сочетания ударения и буквы; они рассматриваются как две кодовые точки. Для простоты в спецификации используется неквалифицированный термин-символ для ссылки на Unicode кодовую точку в исходном тексте.

Каждая кодовая точка отличается; например, заглавные и строчные буквы - это разные символы.

Ограничение реализации: для совместимости с другими инструментами компилятор может запретить символ NUL (U+0000) в исходном тексте.

Ограничение реализации: для совместимости с другими инструментами компилятор может игнорировать метку порядка байтов в кодировке UTF-8 (U+FEFF), если это первая Unicode кодовая точка в исходном тексте. Метка порядка следования байтов может быть запрещена где-либо еще в источнике.

Символы

Следующие термины используются для обозначения определенных классов Unicode символов:

newline        = /* Unicode кодовая точка U+000A */ .
unicode_char   = /* произвольная Unicode кодовая точка исключая newline */ .
unicode_letter = /* Unicode кодовая точка классифицированная как "Letter"(Буква) */ .
unicode_digit  = /* Unicode кодовая точка классифицированная как "Number, decimal digit"(Число, десятичная цифра) */ .

В Unicode стандарте 8.0, Раздел 4.5 "General Category" определяет набор категорий символов. Go рассматривает все символы в любой из Letter категорий Lu, Ll, Lt, Lm, или Lo как Unicode буквы, а все символы в Number категории Nd как Unicode цифры.

Буквы и цифры

Символ нижнего подчеркивания _ (U+005F) считается буквой.

letter        = unicode_letter | "_" .
decimal_digit = "0" … "9" .
octal_digit   = "0" … "7" .
hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .


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