# Типы

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

Тип описывает множество значений, которые имеют одинаковые операции и функции специально для этих значений. Тип определяется именем типа. Ассоциативный массив *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)
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ru.gentee.org/syntax/types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
