Відповіді:
Коли ви об'єднуєте рядки, вам потрібно виділити пам'ять для зберігання результату. Простіше за все почати з 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);
}
Примітка - вся специфікація типу, яку я зробив, є зайвою - компілятор може зробити висновок про всі типи, які тут відтворюються. Я додав їх просто для того, щоб зрозуміти людям, які не знайомі з Рустом, оскільки очікую, що це питання буде популярним у цій групі!
Add
/ +
символ? Ви можете прикрити це, якщо хочете.
Для об'єднання декількох рядків в один рядок, розділених іншим символом, існує кілька способів.
Найприємніше, що я бачив - це використання 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
біса . Ця ознака позначена нестабільною, але її методи стабільні та включені до прелюдії, тому вони можуть бути використані скрізь за замовчуванням. Команда, здається, добре усвідомлює, що ця риса не повинна існувати, і я думаю, що з нею все зміниться в майбутньому.
Я думаю, що цей 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
. Є й інші питання, що деталізують відмінності між ними.