1. Розглядаємо детальніше тип String
Тип String — один із найуживаніших у Kotlin. Можливо, навіть найуживаніший. Це справді зручний тип: у таких змінних можна зберігати текст. А ще, на відміну від типів Int і Double, об’єкти типу String мають чимало різних функцій. З їхньою допомогою можна робити багато цікавого.
Крім того, усі об’єкти в Kotlin (так, буквально всі) можна перетворити на тип String. Якщо сказати точніше, усі об’єкти в Kotlin мають своє текстове (рядкове) подання. Ми ще не раз повертатимемося до цього типу (він і корисний, і цікавий), а сьогодні познайомимося з його основами.
Створення змінних типу String
Тип String призначений для зберігання рядків (тексту). Щоб створити в коді змінну, яка зможе зберігати текст, скористайтеся таким записом:
var імʼя : String
Тут імʼя — це імʼя змінної.
Приклади:
| Команда | Опис |
|---|---|
|
Створюється рядкова змінна name |
|
Створюється рядкова змінна message |
|
Створюється рядкова змінна text |
Так само, як і з типами Int та Double, можна створювати кілька змінних типу String.
У Kotlin запис через кому, як у Java (String a, b;), не використовують — змінні оголошують окремо:
fun main() {
var імʼя 1: String
var імʼя 2: String
var імʼя 3: String
}
2. Присвоювання значень змінним типу String
Щоб записати в змінну типу String значення, скористайтеся таким записом:
імʼя = "значення"
А ось і перша відмінність цього типу від уже вивчених. Усі значення типу String — це рядки тексту, і їх потрібно брати в подвійні лапки.
Приклади:
| Команда | Примітка |
|---|---|
|
Змінна name містить текст Аня |
|
Змінна city містить текст New York |
|
Змінна message містить текст Hello! |
3. Ініціалізація змінних типу String
Як і у випадку з типами Int і Double, змінні типу String можна ініціалізувати одразу під час створення. До речі, так можна робити взагалі з усіма типами в Kotlin, тож більше на цьому не зупинятимемося.
fun main() {
var імʼя 1: String = "значення1"
var імʼя 2: String = "значення2"
var імʼя 3: String = "значення3"
}
fun main() {
var name: String = "Аня"
var city: String = "New York"
var message: String = "Hello!"
}
Використовувати можна лише ініціалізовані змінні
Компілятор Kotlin повідомить про помилку, якщо ви оголосите змінну, не присвоївши їй жодного значення, а потім спробуєте її використати.
Такий код не працюватиме:
fun main() {
var name: String
println(name) // Змінну name не ініціалізовано. Програма не скомпілюється.
}
fun main() {
var a: Int
a++ // Змінну a не ініціалізовано. Програма не скомпілюється.
}
fun main() {
var x: Double
val y = x // Змінну x не ініціалізовано. Програма не скомпілюється.
}
4. Конкатенація — склеювання рядків
Є дуже проста й водночас корисна річ, яку можна робити з рядками в Kotlin, — їх можна склеювати. Така операція називається конкатенацією. Її також називають «склеюванням рядків» або просто «додаванням рядків».
Щоб склеїти два рядки, потрібно використати знак +. Це справді просто:
val result = "рядок1" + "рядок2"
Приклади:
| Команда | Примітка |
|---|---|
|
name містить рядок АняАня |
|
city містить рядок New YorkАня |
|
message містить рядок Hello! Аня |
Ну і, звісно, можна додавати одразу багато рядків, а також поєднувати рядки зі змінними.
Приклади:
fun main() {
val name = "Аня" // name містить рядок Аня
val city = "New York" // city містить рядок New York
val message = "Hello!" + city + name + city // message містить рядок Hello!New YorkАняNew York
}
5. Порожні рядки
З попереднього прикладу видно, що текст у змінній message погано читається, бо в ньому бракує пробілів. Щоб додати один пробіл або кілька, достатньо записати їх у коді та взяти в подвійні лапки. Це простіше, ніж здається:
" "
До речі, якщо між лапками зовсім нічого не залишити (тобто написати дві подвійні лапки підряд), вийде так званий «порожній рядок»:
""
З одного боку, він наче й є, а з іншого — під час виведення на екран нічого не показується. Під час склеювання з іншими рядками теж нічого не змінюється. Такий собі аналог нуля, тільки для рядків.
6. Екранування спецсимволів у рядках
Ви вже знаєте, що рядки беруть у подвійні лапки. Але що робити, якщо потрібно вставити в рядок лапки? Якщо ми запишемо лапки всередині рядка, хіба компілятор не сприйме їх як кінець рядка?
Правильно, сприйме. Тому лапки всередині тексту замінюють парою символів \". Тоді код матиме такий вигляд:
fun main() {
val quote = "Він сказав: \"Вітаю!\""
println(quote) // Він сказав: "Вітаю!"
}
Насправді все трохи хитріше. Символ \ вважається спеціальним (керувальним) усередині рядків. За його допомогою можна задавати різні «недруковані» символи — наприклад, перенесення рядка, табуляцію тощо. А щоб задати сам символ \, його потрібно написати двічі.
Ось чотири найпоширеніші комбінації:
| Запис | Значення |
|---|---|
|
Перенесення рядка (newline) |
|
Табуляція (відступ) |
|
Буквально \ |
|
Лапки всередині рядка |
Приклад:
fun main() {
val multiline = "Рядок 1\nРядок 2"
println(multiline)
}
Виведе:
// Рядок 1
// Рядок 2
7. Власні функції рядків
Тип String має власні функції (їх ще називають методами). Їх дуже багато, і вони полегшують життя програмістам. Сьогодні ви познайомитеся з деякими — найпростішими. Наприклад:
| Функція | Опис | Приклад результату |
|---|---|---|
|
Довжина рядка | |
|
У верхній регістр | |
|
У нижній регістр | |
|
Видалити пробіли по краях | |
Приклади роботи з функціями рядків
Усі ці функції викликаються так: змінна.функція(...).
Визначити довжину рядка:
fun main() {
val name = "Андрій"
val length = name.length
println(length) // 6, бо 6 літер
}
Перетворити рядок у верхній або нижній регістр:
fun main() {
val original = "Привіт"
println(original.uppercase()) // ПРИВІТ
println(original.lowercase()) // привіт
}
Видалити пробіли по краях (дуже корисно під час введення з клавіатури):
fun main() {
val messy = " hello "
println(messy.trim()) // "hello"
}
Кожна така функція повертає новий рядок, а попередній рядок при цьому не змінюється.
8. String templates
$name: підставляємо значення в рядок
Коли конкатенації стає забагато, рядок починає виглядати як «локшина» з лапок, плюсів і пробілів. Kotlin пропонує дуже практичний синтаксис — string templates (рядкові шаблони): усередині рядка можна написати $name, і Kotlin підставить значення змінної. Це частина базового синтаксису мови.
Достатньо написати імʼя змінної зі знаком долара — і Kotlin сам підставить її значення прямо в текст:
fun main() {
val cafe = "Byte & Coffee"
val item = "Latte"
val price = 180
println("=== $cafe ===") // === Byte & Coffee ===
println("Позиція: $item") // Позиція: Latte
println("Ціна: $price ₴") // Ціна: 180 ₴
}
Погодьтеся, очам стало легше — і вам, і тим, хто читатиме ваш код.
${expr}: вставляємо вирази
Форма $name працює, коли потрібно підставити просте імʼя (змінну). Але часто хочеться підставити результат обчислення: суму, добуток, вираз із дужками. Для цього використовують форму ${...}.
Просто додайте фігурні дужки — і всередині можна писати будь-які вирази:
fun main() {
val item = "Latte"
val price = 180
val count = 2
println("Позиція: $item")
println("Ціна за 1: $price ₴")
println("Кількість: $count")
println("Разом: ${price * count} ₴") // Разом: 360 ₴
}
Тут усередині ${...} — звичайний вираз price * count, який ви вже вмієте читати завдяки минулій лекції про Int.
Конкатенація vs templates
Коли обирати +, а коли templates? У більшості випадків templates зручніші. Kotlin навіть у рекомендаціях зі стилю окремо підкреслює цю ідею: фігурні дужки в шаблонах варто використовувати для виразів, а просту змінну вставляти як $name.
| Задача | Конкатенація + | String templates |
|---|---|---|
| Вставити змінну | |
|
| Вставити вираз | |
|
| Не забути пробіли | Потрібно вручну стежити за " " | Зазвичай менше «склеювань», легше помітити |
| Читабельність | Падає за довгих рядків | Зазвичай вища |
Конкатенацію не заборонено, і іноді вона доречна — особливо якщо ви збираєте рядок із багатьох частин поетапно. Але для звичайних повідомлень користувачу templates майже завжди простіші.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ