среда, 3 ноября 2021 г.

Go для Java разработчиков: константы, структуры, указатели

Константы

В Go константы могут быть нетипизированными. Это относится к

  • числовым литералам,
  • выражениям, использующим только нетипизированные константы,
  • и объявлениям const, в которых тип не указан, а выражение инициализатора не типизировано.

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

var a uint
f(a + 1)   // Нетипизированная числовая константа 1 
           // становится типизированной как uint.
f(a + 1e3) // 1e3 также печатается как uint.

Язык не накладывает никаких ограничений на размер нетипизированной числовой константы. Предел применяется только тогда, когда константа используется там, где требуется тип.

const huge = 1 << 100
var n int = huge >> 98

Если тип отсутствует в объявлении переменной и соответствующее выражение оценивается как нетипизированная числовая константа, константа преобразуется в тип rune, int, float64 или complex128 соответственно, в зависимости от того, является ли значение константы символом, целым числом или числом с плавающей запятой, или комплексным числом.

c := 'å'    // rune (псевдоним для int32)
n := 1 + 2  // int
x := 2.7    // float64
z := 1 + 2i // complex128

В Go нет типов перечисления (enum). Вместо этого вы можете использовать специальное имя iota в одном объявлении const, чтобы получить серию возрастающих значений. Когда выражение инициализации опускается для константы, оно повторно использует предыдущее выражение.

const (
    red = iota // red == 0
    blue       // blue == 1
    green      // green == 2
)

Структуры

Структура соответствует классу в Java, но членами структуры не могут быть методы, только переменные. Указатель на структуру похож на ссылочную переменную в Java. В отличие от классов Java, структуры также могут быть определены как прямые значения. В обоих случаях вы используете . (точку) для доступа к членам структуры.

type MyStruct struct {
    s string
    n int64
}

var x MyStruct     // x инициализируется MyStruct{"", 0}.
var px *MyStruct   // px инициализируется nil.
px = new(MyStruct) // px указывает на новую структуру MyStruct{"", 0}.

x.s = "Foo"
px.s = "Bar"

В Go методы могут быть связаны с любым определяемым пользователем типом, а не только со структурами.

Указатели

Если у вас есть int, структура или массив, присваивание копирует содержимое объекта. Чтобы добиться эффекта ссылочных переменных Java, Go использует указатели.

Для любого типа T существует соответствующий тип указателя *T, обозначающий указатели на значения типа T.

Чтобы выделить память для переменной-указателя, используйте встроенную функцию new, которая принимает тип и возвращает указатель на выделенное хранилище. Выделенное пространство будет инициализировано нулевым значением для типа. Например, new(int) выделяет хранилище для нового int, инициализирует его значением 0 и возвращает его адрес, который имеет тип *int.

Код Java T p = new T(), где T - класс с двумя переменными экземпляра a и b типа int, соответствует

type T struct { a, b int }
var p *T = new(T)

или, что более идиоматично

p := new(T)

Объявление var v T, в котором объявляется переменная, содержащая значение типа T, не имеет эквивалента в Java. Значения также могут быть созданы и инициализированы с помощью составного литерала. Например:

v := T{1, 2}

эквивалентно

var v T
v.a = 1
v.b = 2

Для операнда x типа T оператор адреса &x дает адрес x, значение типа *T. Например:

p := &T{1, 2} // p имеет тип *T

Для операнда x типа указателя косвенное обращение к указателю *x обозначает значение, на которое указывает x. Косвенные указатели используются редко; Go, как и Java, может автоматически принимать адрес переменной.

p := new(T)
p.a = 1 // эквивалент (*p).a = 1


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


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

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