Многострочные строки в Rust: как не сойти с ума от кавычек и слешей
Привет, друг! Если ты когда-нибудь писал на Python, то знаешь, что сделать многострочную строку там — проще пареной репы: три кавычки """...""" — и готово. Но стоило тебе перейти на Rust, как ты вдруг понял, что привычный трюк не работает. И вот ты уже гуглишь: «What is the syntax for a multiline string literal?». Знакомо?
Не переживай, это самый популярный вопрос у новичков в Rust, который набрал тысячи просмотров на Stack Overflow. И сегодня мы раз и навсегда разберёмся, как в Rust работать с длинными строками, не сломав себе мозг. Поехали!
Почему Rust не любит тройные кавычки (как Python)?
Rust — язык системный и строгий. Он не прощает вольностей. Тройные кавычки """ в Rust — это не синтаксис для многострочных строк, а начало комментария или документации (если это ///). Так что если ты попробуешь написать:
// ❌ Так не работает!
let text = """Это
многострочная
строка""";
Компилятор посмотрит на тебя с укоризной и выдаст ошибку. В Rust для многострочных строк используется другой подход — и он даже круче, чем в Python!
Способ №1: обычные кавычки и перенос строки
Самый простой способ — просто разорвать строку в коде, используя символ \n внутри строки. Но это скучно и нечитаемо. Гораздо интереснее использовать реальный перенос строки внутри двойных кавычек. Rust позволяет это делать!
// ✅ Работает!
let poem = "Вот пример строки,
которая занимает две строки,
и это абсолютно легально в Rust.";
println!("{}", poem);
Вывод будет содержать символы переноса строки там, где ты их поставил в коде. Но есть нюанс: если ты хочешь сохранить отступы (пробелы в начале строк), они тоже попадут в строку. Иногда это полезно, иногда — нет.
Способ №2: экранирование и обратный слеш — твой друг (и враг)
Если тебе нужно написать длинную строку в коде, но не добавлять в неё переносы строк (например, для читаемости), используй обратный слеш в конце строки:
// ✅ Строка без переносов, но читаемая в коде
let long_string = "Это очень длинная строка, \
которая в коде разбита на несколько строк, \
но в памяти будет одной строкой без \n.";
println!("{}", long_string);
Обрати внимание: после обратного слеша не должно быть пробелов — сразу Enter. Иначе Rust решит, что ты экранируешь пробел, и всё сломается.
Способ №3: Raw String Literals — магия без экранирования
А вот это уже секретное оружие Rust. Если тебе нужно написать строку, содержащую много кавычек, слешей или других спецсимволов (например, JSON, регулярное выражение или Windows-путь), используй r"" — сырые строковые литералы.
Внутри r"..." все символы воспринимаются буквально. Никакого экранирования!
// ✅ Raw string — никаких слешей!
let json = r#"{
"name": "Rust",
"version": 1.75,
"features": ["безопасность", "скорость"]
}"#;
println!("{}", json);
Но как быть, если внутри строки встречается "#? Для этого Rust позволяет увеличивать количество # вокруг кавычек: r##"..."##, r###"..."### и так до бесконечности. Просто выбери такое количество решёток, которое не встречается внутри строки.
// ✅ Raw string с экранированием решёток
let tricky = r###"Строка с "кавычками" и даже "#" внутри!"###;
println!("{}", tricky);
Способ №4: многострочные raw строки — комбайн для сложных данных
А теперь соединим всё вместе. Если тебе нужно написать многострочный блок текста с кавычками, слешами и отступами, используй r#""# с переносами строк прямо внутри:
// ✅ Идеально для конфигов, SQL, HTML
let config = r#"
server {
listen 80;
location / {
proxy_pass http://localhost:8080;
}
}
"#;
println!("{}", config);
Этот код выведет блок с отступами (пробелы и переносы строк сохранятся). Если отступы не нужны — просто пиши без них.
Сравнение с Python: что круче?
Давай честно: Python с его """...""" удобнее для быстрого написания многострочных строк. Но у Rust есть преимущество:
- Raw strings — в Python тоже есть
r"", но он не работает с тройными кавычками. В Rust — работает. - Гибкость экранирования — в Python, если внутри строки есть
""", придётся извращаться. В Rust — просто добавь ещё одну#. - Производительность — Rust компилирует строки на этапе компиляции, нет накладных расходов.
Так что если ты пишешь на Rust — raw строки станут твоим лучшим другом.
Практический пример: SQL-запрос в Rust
Представь, что ты пишешь приложение для работы с базой данных. SQL-запросы часто длинные и содержат кавычки. Вот как это делается правильно:
use std::fs;
fn main() {
// Многострочный SQL-запрос
let query = r#"
SELECT
users.name,
orders.total,
orders.created_at
FROM users
JOIN orders ON users.id = orders.user_id
WHERE orders.total > 100
ORDER BY orders.created_at DESC
LIMIT 10;
"#;
println!("Выполняю запрос: {}", query);
// Здесь ты бы передал query в драйвер БД
}
Чисто, читаемо, без экранирования. Красота!
Частые ошибки и как их избежать
Давай разберём типичные грабли, на которые наступают новички:
- Забыл закрыть кавычку — Rust выдаст ошибку
unterminated double quote string. Всегда проверяй парность. - Пробел после обратного слеша — если после
\в конце строки стоит пробел, Rust не поймёт, что ты хочешь перенести строку. Пиши\сразу перед Enter. - Смешивание raw и обычных строк —
r"..."