JavaRush /Курси /Kotlin SELF /Рядки й текст: тип String, робота з рядками

Рядки й текст: тип String, робота з рядками

Kotlin SELF
Рівень 2 , Лекція 2
Відкрита

1. Розглядаємо детальніше тип String

Тип String — один із найуживаніших у Kotlin. Можливо, навіть найуживаніший. Це справді зручний тип: у таких змінних можна зберігати текст. А ще, на відміну від типів Int і Double, об’єкти типу String мають чимало різних функцій. З їхньою допомогою можна робити багато цікавого.

Крім того, усі об’єкти в Kotlin (так, буквально всі) можна перетворити на тип String. Якщо сказати точніше, усі об’єкти в Kotlin мають своє текстове (рядкове) подання. Ми ще не раз повертатимемося до цього типу (він і корисний, і цікавий), а сьогодні познайомимося з його основами.

Створення змінних типу String

Тип String призначений для зберігання рядків (тексту). Щоб створити в коді змінну, яка зможе зберігати текст, скористайтеся таким записом:

var імʼя : String
Створення змінної типу String

Тут імʼя — це імʼя змінної.

Приклади:

Команда Опис
var name: String
Створюється рядкова змінна name
var message: String
Створюється рядкова змінна message
var text: String
Створюється рядкова змінна text

Так само, як і з типами Int та Double, можна створювати кілька змінних типу String.

У Kotlin запис через кому, як у Java (String a, b;), не використовують — змінні оголошують окремо:

fun main() {
    var імʼя 1: String
    var імʼя 2: String
    var імʼя 3: String
}

2. Присвоювання значень змінним типу String

Щоб записати в змінну типу String значення, скористайтеся таким записом:

імʼя  = "значення"
Присвоювання значення змінній типу String

А ось і перша відмінність цього типу від уже вивчених. Усі значення типу String — це рядки тексту, і їх потрібно брати в подвійні лапки.

Приклади:

Команда Примітка
var name: String = "Аня"
Змінна name містить текст Аня
var city: String = "New York"
Змінна city містить текст New York
var message: String = "Hello!"
Змінна 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"
Конкатенація двох рядків

Приклади:

Команда Примітка
val name = "Аня" + "Аня"
name містить рядок АняАня
val city = "New York" + "Аня"
city містить рядок New YorkАня
val message = "Hello! " + "Аня"
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) // Він сказав: "Вітаю!"
}

Насправді все трохи хитріше. Символ \ вважається спеціальним (керувальним) усередині рядків. За його допомогою можна задавати різні «недруковані» символи — наприклад, перенесення рядка, табуляцію тощо. А щоб задати сам символ \, його потрібно написати двічі.

Ось чотири найпоширеніші комбінації:

Запис Значення
\n
Перенесення рядка (newline)
\t
Табуляція (відступ)
\\
Буквально \
\"
Лапки всередині рядка

Приклад:

fun main() {
    val multiline = "Рядок 1\nРядок 2"
    println(multiline)
}

Виведе:

// Рядок 1
// Рядок 2

7. Власні функції рядків

Тип String має власні функції (їх ще називають методами). Їх дуже багато, і вони полегшують життя програмістам. Сьогодні ви познайомитеся з деякими — найпростішими. Наприклад:

Функція Опис Приклад результату
str.length
Довжина рядка
"abc".length → 3
str.uppercase()
У верхній регістр
"abc".uppercase() → "ABC"
str.lowercase()
У нижній регістр
"ABC".lowercase() → "abc"
str.trim()
Видалити пробіли по краях
"  x y  ".trim() → "x y"

Приклади роботи з функціями рядків

Усі ці функції викликаються так: змінна.функція(...).

Визначити довжину рядка:

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
Вставити змінну
"Привіт, " + name
"Привіт, $name"
Вставити вираз
"Разом: " + (a + b)
"Разом: ${a + b}"
Не забути пробіли Потрібно вручну стежити за " " Зазвичай менше «склеювань», легше помітити
Читабельність Падає за довгих рядків Зазвичай вища

Конкатенацію не заборонено, і іноді вона доречна — особливо якщо ви збираєте рядок із багатьох частин поетапно. Але для звичайних повідомлень користувачу templates майже завжди простіші.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ