· 7 мин 👁 1.1k Начинающий

Язык Gleam — строки

Строки в Gleam: UTF-8, многострочные литералы, escape-последовательности, конкатенация и функции стандартной библиотеки.

gleamstringстрокиutf-8unicode
Содержание

Разбираем строки в Gleam на примерах — с дополнительными тонкостями, которые пригодятся на практике.

Основы

Строки в Gleam — двойные кавычки, UTF-8, без ограничений на содержимое:

import gleam/io
import gleam/string

pub fn main() {
  // Emoji, японский, латиница — всё в одной строке
  io.println("👩‍💻 こんにちは Gleam 🏳️‍🌈")

  // Многострочная строка
  io.println(
    "multi
    line
    string",
  )

  // Unicode codepoint напрямую
  io.println("\u{1F600}")  // 😀

  // Экранирование двойной кавычки
  io.println("\"X\" marks the spot")

  // Конкатенация
  io.println("One " <> "Two")

  // Функции стандартной библиотеки
  io.println(string.reverse("1 2 3 4 5"))
  io.println(string.append("abc", "def"))
}

Строки в Gleam всегда UTF-8 — это гарантия платформы, а не просто соглашение. Нельзя создать строку с невалидной байтовой последовательностью через строковый литерал. Если нужно работать с произвольными байтами — для этого есть отдельный тип BitArray.

Escape-последовательности

Полный список того, что можно написать внутри строки:

ПоследовательностьЗначение
\"двойная кавычка
\\обратный слэш
\fform feed (перевод страницы)
\nновая строка
\rвозврат каретки
\tтабуляция
\u{xxxxxx}Unicode codepoint

\u{xxxxxx} принимает от одной до шести шестнадцатеричных цифр. \u{1F600} — это 😀, \u{41} — это A. Фигурные скобки обязательны — в отличие от некоторых других языков, где пишут \u0041 без скобок.

Одинарные кавычки экранировать не нужно — в Gleam они не имеют специального значения в строках. "it's fine" пишется как есть.

Многострочные строки

let query = "
  SELECT *
  FROM users
  WHERE active = true
"

Отступы становятся частью строки. Если это важно — используйте string.trim или string.trim_start:

import gleam/string

let indented = "  hello  "
echo string.trim(indented)        // "hello"
echo string.trim_start(indented)  // "hello  "
echo string.trim_end(indented)    // "  hello"

Конкатенация и сборка строк

Оператор <> склеивает две строки:

let name = "Joe"
let greeting = "Hello, " <> name <> "!"
echo greeting  // "Hello, Joe!"

Для сборки строки из многих частей удобнее string.concat, который принимает список:

import gleam/string

let parts = ["Gleam", " ", "is", " ", "great"]
echo string.concat(parts)  // "Gleam is great"

Многократная конкатенация через <> в цикле — плохая идея по тем же причинам, что и в большинстве языков: каждый <> создаёт новую строку в памяти. Если собираете строку из множества частей — собирайте список и вызывайте string.concat один раз в конце.

Полезные функции из gleam/string

Стандартная библиотека покрывает большинство повседневных задач:

import gleam/string

// Длина в графемах (не байтах)
echo string.length("hello")   // 5
echo string.length("こんにちは")  // 5, не 15

// Проверки
echo string.is_empty("")         // True
echo string.contains("hello", "ell")  // True
echo string.starts_with("gleam", "gl")  // True
echo string.ends_with("gleam", "am")    // True

// Преобразования
echo string.uppercase("hello")  // "HELLO"
echo string.lowercase("HELLO")  // "hello"
echo string.capitalise("hello") // "Hello"

// Разбивка и замена
echo string.split("a,b,c", ",")         // ["a", "b", "c"]
echo string.replace("hello", "l", "r")  // "herro"

// Срезы
echo string.slice("hello", 1, 3)  // "ell"
// slice(строка, с_позиции, длина)

string.length считает графемы — воспринимаемые пользователем символы, а не байты и не кодовые точки Unicode. Эмодзи из нескольких codepoint’ов (👩‍💻 — это пять codepoint’ов, склеенных zero-width joiner’ом) считается как один символ. Это поведение правильное для большинства задач, но медленнее байтового подсчёта — держите это в голове, если обрабатываете огромные строки в горячем пути.

Преобразование в строку и обратно

Числа в строку и обратно — через модули int и float:

import gleam/int
import gleam/float

echo int.to_string(42)         // "42"
echo float.to_string(3.14)     // "3.14"

echo int.parse("42")           // Ok(42)
echo int.parse("abc")          // Error(Nil)
echo float.parse("3.14")       // Ok(3.14)

int.parse возвращает Result(Int, Nil), а не просто Int — потому что парсинг может не получиться. Компилятор заставит обработать оба случая. Это именно то место, где в других языках легко получить runtime-исключение, а в Gleam — ошибку компилятора, если вы забыли обработать Error.

Итоги

  • Строки всегда UTF-8 и всегда валидные — это гарантия языка
  • <> — конкатенация; для сборки из многих частей лучше string.concat
  • \u{xxxxxx} — Unicode codepoint с фигурными скобками
  • string.length считает графемы, а не байты
  • Многострочные строки сохраняют отступы — используйте string.trim если нужно
  • int.parse и float.parse возвращают Result, не бросают исключений