02. Declarations
Declarations
Имеется 4 вида объявлений в Go:
var
для переменныхconst
для константfunc
для функцийtype
для типов
Объявление в функции локальной переменной может затемнить объявление пакета. Если есть пакет bytes
, то локальная переменная bytes
перекроет его.
Variables
The var
statement declares a list of variables; as in function argument lists, the type is last.
A
var
statement can be at package or function level.A
var
declaration can include initialisers, one per variable.If an initialiser is present, the type can be omitted; the variable will take the type of the initializer.
Если значение не указано, то значением переменной будет значение по умолчанию для своего типа. В Go не существует такого понятия как неинициализированная переменная.
In Go, some values are addressable (there is an address to find them). All variables are addressable and all constants are unaddressable.
There is also declaration list:
Short variable declarations
Inside a function, the :=
short assignment statement can be used in place of a var
declaration with implicit type. Outside a function, every statement begins with a keyword (var
, func
, and so on) and so the :=
construct is not available.
Однако краткое объявление должно объявлять хоть одну новую переменную, остальные оно перезапишет.
В локальных блоках, короткое объявление действует как объявление новой переменной и затемняет внешнюю переменную.
Because :=
only reuses variables that are declared in the current block. When using :=
, make sure that you don’t have any variables from an outer scope on the lefthand side, unless you intend to shadow them.
Type inference
When declaring a variable without specifying an explicit type (either by using the :=
syntax or var =
expression syntax), the variable's type is inferred from the value on the right hand side.
Choosing declaration type
How do you know which style to use? As always, choose what makes your intent clearest.
The most common declaration style within functions is
:=
.Outside of a function, use declaration lists on the rare occasions when you are declaring multiple package-level variables.
There are some situations within functions where you should avoid :=
:
When initialising a variable to its zero value, use
var x int
. This makes it clearthat the zero value is intended.
When assigning an untyped constant or a literal to a variable and the default type for the constant or literal isn’t the type you want for the variable, use the long var form with the type specified. While it is legal to use a type conversion to specify the type of the value and use
:=
to writex := byte(20)
, it is idiomatic to writevar x byte = 20
.Because
:=
allows you to assign to both new and existing variables, it sometimes creates new variables when you think you are reusing existing ones. In those situations, explicitly declare all of your new variables withvar
to make it clear which variables are new, and then use the assignment operator (=
) to assign values to both new and old variables.
You should rarely declare variables outside of functions, in what’s called the package block. Package-level variables whose values change are a bad idea. When you have a variable outside of a function, it can be difficult to track the changes made to it, which makes it hard to understand how data is flowing through your program. This can lead to subtle bugs. As a general rule, you should only declare variables in the package block that are effectively immutable.
Constants
Константы в Go имеют особую семантику:
Constants are declared like variables, but with the
const
keyword.A
const
statement can appear anywhere avar
statement can.Constants can be character, string, boolean, or numeric values.
Constants in Go a the way to give a names to literals.
Constants cannot be declared using the
:=
syntax.Constants assigned at its declaration at compile-time.
Constants must be compile-time values
const two = math.Sqrt(4)
won't work.Constants can be typed or untyped:
An untyped constant takes the type needed by its context.
A typed constant have explicit type.
Integer constants default to
int
, floating-point constantsfloat64
,rune
constants torune
(an alias forint32
), and imaginary constants tocomplex128
.Если имеется выражение из const, то тип результата зависит от типа последнего операнда в списке (что странно).
1 / 3
все равно даст1
,1 / 2
тоже даст1
. То есть константы все же не ведут себя как числа.In Go, some values are addressable (there is an address to find them). All variables are addressable and all constants are unaddressable. You can’t access it from its memory address. Unlike variables constants can't have pointers.
При групповом определении констант работает авто-дополнение:
Untyped constants
Untyped константа имеет значение, но не имеет стандартного типа из языка go. Она как и любая переменная хранится в памяти, и может быть использована, но у нее есть kind (разновидность), но не тип.
Kind константы определяется исходя из её значения. Значение константы называется идеальным значением (ideal value) и принадлежит к какому-то идеальному типу в математическом смысле (целые, вещественные, логические и т.д.). В зависимости от литерала константы Go преобразует это значение в какой-то из своих типов и назначает константе этот тип (default type):
Ideal type | Default type
boolean
→bool
rune
→rune
integer
→int
floating
→float64
string
→string
nil
→ none
Поэтому константы могут иметь значения которые не могут иметь переменные обычных типов Go.
Представление констант в памяти зависит от компилятора, но в целом они должны представляться одинаковыми значениями на разных платформах.
Вычисления над константами и литералами осуществляются во время компиляции, а не во время работы программы. Компилятор Go написан на Go. Нетипированные цифровые константы поддерживаются пакетом big
, позволяя использовать все обычные операции с числами.
iota
-expressions
iota
-expressionsiota
starts constant numbering in Go. It doesn't mean “start from zero” as someone might expect. It is an index of a constant in the current const block:
iota
изначально равна0
и увеличивается на1
для каждой следующей константы.если для вычисления значения константы используется какое-то выражение в котором есть
iota
, то по умолчанию это выражение применяется и для последующих констант, но уже с увеличенным значениемiota
.пустая переменная может использоваться для инкремента
iota
значения.iota
could be used to simulateC
’s enum or#define
constant.The
iota
increments on the next line, rather than as soon as it gets referenced.
Классический пример:
Custom Types
type
выражение определяет новый тип.type
выражения можно использовать внутри функций
Auto-incrementing constants are often combined with a custom type, allowing you to lean on the compiler.
Enums
Here’s an idiomatic way to implement an enumerated type:
create a new integer type,
list its values using
iota
,give the type a
String
function.
In use:
Assignability
Having variable left
of type T
, there are 5 cases when value right
can be assigned to left
.
Identical types
Identical underlying types
Assigning to interface type
T
value implementingT
Assigning
nil
to variable which is a pointer, function, slice, map, channel or interface type.Untyped constants. Untyped constant can be set to variable of type
T
if constant is representable by value of typeT
.
Last updated
Was this helpful?