Added kotlin guide. (WIP) (15.10.26)

This commit is contained in:
2026-10-15 00:24:21 +03:00
parent dc82207723
commit da3ad9dd1a
13 changed files with 2120 additions and 0 deletions
@@ -0,0 +1,154 @@
---
title: Типы данных
description: Система типов Kotlin, числа, boolean, Char и отсутствие примитивов на уровне языка
tags:
- kotlin
- types
---
В Kotlin: статическая типизация, сильная, с выводом типов.
Главное отличие от Java: **на уровне языка примитивов нет**. Всё - объект, у всего есть методы.
```kotlin
val x: Int = 42
println(x.toString()) // у числа есть методы
println(42.coerceIn(0, 10)) // 10
```
Но в байт-коде `Int` компилируется в `int`, если это возможно - производительность не теряется. Подробнее в [Kotlin в байт-коде](../../Взаимодействие%20с%20Java/Kotlin%20в%20байт-коде.md).
## Иерархия типов
```mermaid
graph TD
Any["Any — корень всех non-null типов"]
Any --> Number
Any --> Char
Any --> Boolean
Any --> String
Any --> Other["классы, интерфейсы, ..."]
Number --> Byte
Number --> Short
Number --> Int
Number --> Long
Number --> Float
Number --> Double
Nothing["Nothing — наследник всех типов"]
```
`Any`, `Unit` и `Nothing` - особые типы, им посвящена отдельная заметка: [Any, Unit, Nothing](../Базовые%20типы%20ООП/Any,%20Unit,%20Nothing.md)
## Числовые типы
| Тип | Размер, бит | Диапазон |
|---|---|---|
| `Byte` | 8 | −128 … 127 |
| `Short` | 16 | −32 768 … 32 767 |
| `Int` | 32 | ≈ ±2 млрд |
| `Long` | 64 | ≈ ±9,2 · 10¹⁸ |
| `Float` | 32 | ≈ 6-7 значащих цифр |
| `Double` | 64 | ≈ 15-16 значащих цифр |
Все наследуются от `Number`, но **не** друг от друга: `Int` не является подтипом `Long`.
### Литералы
```kotlin
val i = 42 // Int по умолчанию
val l = 42L // Long — суффикс L
val d = 42.0 // Double по умолчанию
val f = 42.0f // Float — суффикс f
val hex = 0xFF // 255
val bin = 0b1010 // 10
val big = 1_000_000 // подчёркивания для читаемости
```
Восьмеричных литералов (`017` в Java) в Kotlin **нет**.
## Беззнаковые типы
`UByte`, `UShort`, `UInt`, `ULong` - то, чего в Java нет совсем.
```kotlin
val u: UInt = 4_000_000_000u // суффикс u
println(UInt.MAX_VALUE) // 4294967295
```
Нужны редко: работа с бинарными форматами, протоколами, хешами.
## Boolean
```kotlin
val yes: Boolean = true
val both = yes && other() // ленивые операторы, как в Java
val eager = yes and other() // не ленивый: other() вызовется всегда
```
## Char
```kotlin
val c: Char = 'A'
println(c.code) // 65 — числовой код
println(c + 1) // B — Char + Int даёт Char
println(c.isLetter()) // true
```
`Char` **не является числом**: `val n: Int = 'A'` не скомпилируется, нужен `'A'.code`.
Подробнее: [Char](../Работа%20с%20данными/Char.md)
## Преобразования
Неявных расширяющих преобразований нет вообще - только явные вызовы:
```kotlin
val i = 42
val l: Long = i.toLong() // обязательно явно
val b = i.toByte()
val d = i.toDouble()
```
Доступны `toByte()`, `toShort()`, `toInt()`, `toLong()`, `toFloat()`, `toDouble()`, `toChar()`.
## Строки
`String` - неизменяемый тип, элементы доступны по индексу:
```kotlin
val s = "Kotlin"
println(s[0]) // K
println(s.length) // 6
```
Подробнее: [Строки](../Работа%20с%20данными/Строки.md)
## Nullable-типы
Любой тип имеет nullable-вариант с `?`:
```kotlin
// val a: Int = null // ошибка компиляции
val b: Int? = null // ok
```
Это ядро языка, ему посвящён отдельный раздел: [Null-безопасность](../Null-безопасность/Null-безопасность.md)
> [!info] Отличия от Java
> | Java | Kotlin |
> |---|---|
> | `int` и `Integer` - разные типы | только `Int`, компилятор сам выбирает представление |
> | автоупаковка неявная | упаковка скрыта, в коде не видна |
> | `long x = intValue;` работает | нужен `intValue.toLong()` |
> | `char` - числовой тип | `Char` - отдельный тип, не число |
> | нет беззнаковых типов | `UInt`, `ULong`, … |
> | `017` - восьмеричный литерал | восьмеричных литералов нет |
>
> Сравнить: [Типы данных в Java](../../../Программирование%20на%20Java/Синтаксис%20и%20типы/Базовый%20синтаксис/Типы%20данных.md)
> [!warning] Подводные камни
> **Переполнение не проверяется**, как и в Java:
> ```kotlin
> println(Int.MAX_VALUE + 1) // -2147483648
> ```
>
> **Равенство упакованных значений.** Если тип nullable, значение упаковано, и `===` сравнивает ссылки:
> ```kotlin
> val a: Int = 127
> val b: Int? = a
> val c: Int? = a
> println(b == c) // true — сравнение значений
> println(b === c) // true — кеш Integer для -128..127
>
> val x: Int? = 1000
> val y: Int? = 1000
> println(x == y) // true
> println(x === y) // false — за пределами кеша это разные объекты
> ```
> Вывод: для чисел всегда `==`, никогда `===`.
>
> **`Float` и `Double` не точны**, это стандарт IEEE 754:
> ```kotlin
> println(0.1 + 0.2) // 0.30000000000000004
> ```
> Для денег - `java.math.BigDecimal`.
Дополнительно: [Числа и переполнение](../Работа%20с%20данными/Числа%20и%20переполнение.md)
Далее: [Переменные](Переменные.md)