Ответы:
Когда вы объединяете строки, вам нужно выделить память для хранения результата. Проще всего начать с Stringи &str:
fn main() {
let mut owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
owned_string.push_str(borrowed_string);
println!("{}", owned_string);
}
Здесь у нас есть собственная строка, которую мы можем изменить. Это эффективно, поскольку потенциально позволяет нам повторно использовать выделение памяти. Там аналогичный случай для Stringи String, как &String можно разыменовать как&str .
fn main() {
let mut owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
owned_string.push_str(&another_owned_string);
println!("{}", owned_string);
}
После этого another_owned_stringостается нетронутым (примечание без mutуточнения). Там еще один вариант , который потребляетString , но не требует от него быть изменяемыми. Это реализация Addчерты, которая принимает Stringкак левую сторону, а &strкак правую:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let new_owned_string = owned_string + borrowed_string;
println!("{}", new_owned_string);
}
Обратите внимание, что owned_stringбольше не доступно после звонка +.
Что если мы хотим создать новую строку, оставив обе нетронутыми? Самый простой способ - использовать format!:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Обратите внимание, что обе входные переменные являются неизменяемыми, поэтому мы знаем, что они не затрагиваются. Если мы хотим сделать то же самое для любой комбинации String, мы можем использовать тот факт, что Stringтакже может быть отформатирован:
fn main() {
let owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
let together = format!("{}{}", owned_string, another_owned_string);
println!("{}", together);
}
Вы не должны использовать format!все же. Вы можете клонировать одну строку и добавить другую строку к новой строке:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Примечание: все спецификации типов, которые я сделал, являются избыточными - компилятор может вывести здесь все типы в игре. Я добавил их просто для ясности новичкам в Rust, так как я ожидаю, что этот вопрос будет популярен в этой группе!
Add/ +символ? Вы можете покрыть это, если хотите.
.to_owned()и .to_string()было исправлено с момента вышеупомянутого комментария благодаря подразумеваемой специализации. Теперь они оба имеют одинаковую производительность при вызове &str. Соответствующий коммит: github.com/rust-lang/rust/pull/32586/files
Чтобы объединить несколько строк в одну строку, разделенную другим символом, существует несколько способов.
Самое приятное, что я видел, это использование joinметода в массиве:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
В зависимости от вашего варианта использования вы также можете предпочесть больше контроля:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Я видел еще несколько ручных способов, некоторые избегают одного или двух распределений здесь и там. Для удобства чтения я считаю, что вышеупомянутых двух будет достаточно.
joinна самом деле привязан к этой SliceContactExtчерте . Черта помечена как нестабильная, но ее методы стабильны и включены в Prelude, поэтому по умолчанию их можно использовать везде. Команда, кажется, хорошо знает, что эта черта не должна существовать, и я думаю, что в будущем все изменится.
Я думаю, что этот concatметод и +должен быть упомянут здесь также:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
и есть также concat!макрос, но только для литералов:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+уже упоминалось в существующем ответе . ( Это реализация Addпризнака , который принимает в Stringкачестве стороны левой стороны , и &strкак с правой стороны: )
В RUST доступны различные методы для объединения строк
concat!()):fn main() {
println!("{}", concat!("a", "b"))
}
Вывод вышеуказанного кода:
аб
push_str()и +оператор):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = "c".to_string();
_a.push_str(&_b);
println!("{}", _a);
println!("{}", _a + &_b);
}
Вывод вышеуказанного кода:
аб
азбука
Using format!()):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
Вывод вышеуказанного кода:
аб
проверить это и поэкспериментировать с игровой площадкой Rust
strи&strэто разные типы и в 99% случаев вам нужно только позаботиться&str. Есть и другие вопросы, детализирующие различия между ними.