Kotlin guide done. (20.10.26)
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Char
|
||||
description: Char как отдельный тип, код символа, проверки категорий и работа с цифрами
|
||||
tags:
|
||||
- kotlin
|
||||
- stdlib
|
||||
---
|
||||
|
||||
`Char` - один символ в одинарных кавычках. Хранит кодовую единицу UTF-16 (16 бит).
|
||||
|
||||
```kotlin
|
||||
val c: Char = 'A'
|
||||
val tab = '\t'
|
||||
val quote = '\''
|
||||
val unicode = '\u00A9' // ©
|
||||
```
|
||||
|
||||
Ключевое отличие от Java: **`Char` не является числом**. Арифметику с ним делать можно, но неявного превращения в `Int` нет.
|
||||
|
||||
```kotlin
|
||||
val c = 'A'
|
||||
// val n: Int = c // ошибка компиляции
|
||||
val n: Int = c.code // 65 — явно
|
||||
println(c + 1) // B — Char + Int = Char
|
||||
println('z' - 'a') // 25 — Char - Char = Int
|
||||
println(c.toString()) // A
|
||||
```
|
||||
|
||||
| Выражение | Результат | Тип |
|
||||
|---|---|---|
|
||||
| `'A' + 1` | `'B'` | `Char` |
|
||||
| `'z' - 'a'` | `25` | `Int` |
|
||||
| `'A'.code` | `65` | `Int` |
|
||||
| `65.toChar()` | `'A'` | `Char` |
|
||||
|
||||
## Проверки категорий
|
||||
```kotlin
|
||||
println('a'.isLetter()) // true
|
||||
println('5'.isDigit()) // true
|
||||
println('a'.isLetterOrDigit()) // true
|
||||
println(' '.isWhitespace()) // true
|
||||
println('a'.isLowerCase()) // true
|
||||
println('A'.isUpperCase()) // true
|
||||
```
|
||||
Все эти функции учитывают Unicode: `'я'.isLetter()` тоже `true`.
|
||||
|
||||
## Регистр
|
||||
```kotlin
|
||||
println('a'.uppercaseChar()) // A — возвращает Char
|
||||
println('A'.lowercaseChar()) // a
|
||||
println('a'.uppercase()) // "A" — возвращает String
|
||||
println('ß'.uppercase()) // "SS" — два символа, поэтому String
|
||||
```
|
||||
Есть две версии: `uppercaseChar()` даёт `Char`, `uppercase()` - `String`. Вторая нужна, потому что в Unicode регистр не всегда меняется один-к-одному.
|
||||
|
||||
## Цифры
|
||||
```kotlin
|
||||
println('7'.digitToInt()) // 7 — число, а не код символа
|
||||
println('f'.digitToInt(16)) // 15
|
||||
println('x'.digitToIntOrNull()) // null — безопасная версия
|
||||
println(7.digitToChar()) // '7'
|
||||
```
|
||||
Это главный способ разобрать цифру. Старый трюк из Java (`c - '0'`) тоже работает, но `digitToInt()` понятнее и проверяет корректность:
|
||||
```kotlin
|
||||
println('7' - '0') // 7 — работает
|
||||
// println('x'.digitToInt()) // IllegalArgumentException
|
||||
```
|
||||
|
||||
## Диапазоны и сравнение
|
||||
```kotlin
|
||||
println('a' in 'a'..'z') // true
|
||||
println('5' in '0'..'9') // true
|
||||
for (c in 'a'..'e') print(c) // abcde
|
||||
println('a' < 'b') // true — по коду
|
||||
println(('a'..'e').toList()) // [a, b, c, d, e]
|
||||
```
|
||||
|
||||
## Строки и Char
|
||||
```kotlin
|
||||
val s = "Kotlin"
|
||||
println(s[0]) // K — элемент строки это Char
|
||||
println(s.first()) // K
|
||||
println(s.toCharArray().size) // 6
|
||||
println(String(charArrayOf('a','b'))) // ab — собрать строку из массива
|
||||
println(s.toList()) // [K, o, t, l, i, n]
|
||||
println("abc".map { it + 1 }) // [b, c, d]
|
||||
println(charArrayOf('a','b').concatToString()) // ab
|
||||
```
|
||||
|
||||
Приписать `Char` к строке можно сложением - слева обязательно строка:
|
||||
```kotlin
|
||||
println("ab" + 'c') // abc
|
||||
// println('c' + "ab") // ошибка: Char.plus ожидает Int
|
||||
println("${'c'}ab") // cab — через шаблон
|
||||
```
|
||||
|
||||
> [!info] Отличия от Java
|
||||
> | Java | Kotlin |
|
||||
> |---|---|
|
||||
> | `char` - числовой тип | `Char` - отдельный тип |
|
||||
> | `int n = c;` работает | нужен `c.code` |
|
||||
> | `Character.isDigit(c)` | `c.isDigit()` |
|
||||
> | `Character.toUpperCase(c)` | `c.uppercaseChar()` |
|
||||
> | `Character.getNumericValue(c)` | `c.digitToInt()` |
|
||||
> | `c - '0'` для цифры | `c.digitToInt()` |
|
||||
> | `switch (c)` по числам | `when (c)` по символам |
|
||||
>
|
||||
> В Java `char` участвует в арифметике как число, из-за чего `System.out.println('a' + 1)` печатает `98`, а не `b`. В Kotlin тот же код даёт `b` - тип сохраняется.
|
||||
>
|
||||
> Все утилиты из `Character` стали методами `Char`, поэтому пишутся через точку и находятся автодополнением.
|
||||
>
|
||||
> Сравнить: [Character в Java](../../../Программирование%20на%20Java/Синтаксис%20и%20типы/Работа%20с%20данными%20и%20типами/Character.md)
|
||||
|
||||
> [!warning] Подводные камни
|
||||
> **`Char` не вмещает символы за пределами BMP.** Эмодзи и редкие иероглифы кодируются двумя `Char` (surrogate pair):
|
||||
> ```kotlin
|
||||
> val emoji = "😀"
|
||||
> println(emoji.length) // 2
|
||||
> println(emoji[0].isLetter()) // false — половина пары бессмысленна
|
||||
> println(emoji.codePointAt(0)) // 128512 — полный код символа
|
||||
> ```
|
||||
> Для посимвольной обработки текста с эмодзи нужны кодовые точки, а не `Char`.
|
||||
>
|
||||
> **`digitToInt()` бросает исключение, а не возвращает -1:**
|
||||
> ```kotlin
|
||||
> println('x'.digitToIntOrNull()) // null — безопасно
|
||||
> // println('x'.digitToInt()) // IllegalArgumentException
|
||||
> ```
|
||||
>
|
||||
> **`'1'.code` - это 49, а не 1.** Путать код символа с его числовым значением - классическая ошибка:
|
||||
> ```kotlin
|
||||
> println('1'.code) // 49
|
||||
> println('1'.digitToInt()) // 1
|
||||
> ```
|
||||
>
|
||||
> **`Char` в `when` требует `else`** - перечислить все 65 536 значений компилятор не может.
|
||||
>
|
||||
> **`uppercase()` возвращает `String`, и это не придирка.** `'ß'.uppercase()` даёт `"SS"` - два символа. Если нужен именно `Char`, используйте `uppercaseChar()`, но помните, что для `'ß'` он вернёт сам `'ß'`.
|
||||
|
||||
Далее: [Числа и переполнение](Числа%20и%20переполнение.md)
|
||||
Reference in New Issue
Block a user