> For the complete documentation index, see [llms.txt](https://ru.gentee.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ru.gentee.org/syntax/types.md).

# Типы

## Определение типа

Тип описывает множество значений, которые имеют одинаковые операции и функции специально для этих значений. Тип определяется именем типа. Ассоциативный массив *map* - это группа элементов одного типа к которой можно обращаться по строковому индексу. Каждый элемент имеет соответствующий уникальный строковый ключ. По умолчанию, массивы *arr* и *map* состоят из строк, но вы можете указать любую вложенность типов, разделив их точкой. Следует заметить, что переменные типов **arr**, **map**, **buf**, **set**, **obj** и типов определенных с помощью **struct**, в отличии от прочих типов, передаются по ссылке, а не по значению. Это значит, что если внутри функции вы изменили значение такого параметра, то у вас изменится оригинальная переменная.

```go
TypeName  = identifier  { "." identifier }
```

Язык Gentee содержит следующие предопределенные типы.

**arr bool buf char error finfo float handle int map obj range set str time trace thread**

| Имя        | Описание                      | Значения                                        | Начальное значение                |
| ---------- | ----------------------------- | ----------------------------------------------- | --------------------------------- |
| **int**    | 64-bit целочисленный тип      | -9223372036854775808 .. 9223372036854775807     | 0                                 |
| **float**  | 64-bit тип с плавающей точкой | 2.22 E–308 ..    1.79 E+308                     | 0.0                               |
| **bool**   | логический тип                | *true* or *false*                               | false                             |
| **str**    | строка                        | последовательность байт                         | пустая строка                     |
| **char**   | Unicode символ                | Unicode символ int32                            | пробел                            |
| **arr**    | массив                        | массив элементов                                | пустой массив строк               |
| **map**    | ассоциативный массив          | ассоциативный массив элементов                  | пустой ассоциативный массив строк |
| **buf**    | массив байт                   | последовательность uint8                        | пустой массив                     |
| **set**    | массив bool                   | последовательность uint64 по 1 биту на значение | пустоe множество                  |
| **obj**    | объект                        | int, bool, float, str, arr.obj, map.obj         | nil                               |
| **handle** | скрытый тип                   | любые типы на Go                                | nil                               |

Тип **handle** используется для передачи значений между встроенными Golang функциями. Переменная данного типа может содержать значение любого Golang типа. Go функции должны следить за типами полученных значений, которые в Gentee описаны как *handle*.

```go
arr.map.int a
map.arr.str b   // the same as map.arr b
map.bool c
arr.int  d
```

## Приведение типов

В языке Gentee отсутствует автоматическое приведение типов. Для основных типов имеются функции конвертирования из одного типа в другой, их имена совпадают с именем результирующего типа.

|       | int       | bool       | str             | char     | float      |
| ----- | --------- | ---------- | --------------- | -------- | ---------- |
| int   |           | int(false) | int("-23")      | int('A') | int(3.24)  |
| bool  | bool(1)   |            | bool("0")       |          | bool(1.1)  |
| str   | str(20)   | str(false) |                 | str('z') | str(5.662) |
| char  |           |            |                 |          |            |
| float | float(10) |            | float("-2E-34") |          |            |

```go
int(false) // = 0           
int(true) // = 1    
bool(0) // = false  
bool(0.) // = false
bool(integer except zero) // = true    
bool("")  bool("0") bool("false") //=false
bool("not empty, zero or false string")   //=true
```

## Структурные типы

Вы можете определить структурный тип с помощью ключевого слова **struct**. Укажите имя типа после ключевого слова и перечислите типы и имена полей внутри фигурных скобок. Все поля в переменной структурного типа инициализируются автоматически. Все переменные таких типов при передаче в функции передаются по ссылке, а не по значению. Для присваивания или получения значения поля, укажите его имя после точки.

```go
structDecl = "struct" identifier "{" FieldDecl { newline  FieldDecl } "}"
FieldDecl = TypeName identifier
FieldExpr = PrimaryExpr "." identifier
```

```go
struct my : int ID; str name
struct myStruct {
      int ID
      my myval
      arr st_arr
      map.int st_map
}
run int {
    myStruct ms
    ms.ID = 20
    return ms.ID * 2
}
```

## Тип функции

Язык Gentee позволяет работать с идентификаторами функций. Вы можете получить идентификатор функции, передать его в качестве параметра и вызвать соответствующую функцию. Для работы с идентификаторами функций вы должны определить тип функции с помощью ключевого слова **fn** и указать типы параметров и возвращаемого значения. Для получения идентификатора функции укажите **&имяфункции.fnтип**. Идентификатор функции может передаваться в параметрах или присваиваться переменной соответствующего типа. Для вызова функции по её идентификатору достаточно указать имя переменной и круглые скобки с параметрами, как при вызове функции по имени.

Получение идентификатора функций не применимо к следующим функциям:

* Встроенные функции.
* Функции с переменным количеством параметров.
* Функции с опциональными переменными.

```go
fnDecl = "fn" FnName [FnParameters] [ TypeName ]
FnName = identifier
FnParameters     = "(" [ FnParameterList ] ")"
FnParameterList  = TypeName { [","] TypeName }
FnIdent = "&" FuncName "." FnName
```

```go
fn bin( int int ) int
func add( int i, int j ) int : return i + j
func sub( int i, int j ) int : return i - j
func mybin(int i j, bin f ) int : return j + f(i, j)

run int {
  bin isub = &sub.bin
  return mybin(1, 2, &add.bin) + mybin(3, 7, isub)
}
```
