Câu trả lời:
Khi bạn nối chuỗi, bạn cần phân bổ bộ nhớ để lưu trữ kết quả. Cách dễ nhất để bắt đầu là String
và &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);
}
Ở đây, chúng ta có một chuỗi sở hữu mà chúng ta có thể đột biến. Điều này rất hiệu quả vì nó có khả năng cho phép chúng ta sử dụng lại việc cấp phát bộ nhớ. Có một trường hợp tương tự cho String
và String
, như &String
có thể được quy định là&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);
}
Sau này, another_owned_string
không bị ảnh hưởng (lưu ý không có mut
vòng loại). Có một biến thể mà tiêu thụ các String
nhưng không đòi hỏi nó là có thể thay đổi. Đây là một cách thực hiện các Add
đặc điểm lấy String
bên trái và &str
bên phải:
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);
}
Lưu ý rằng owned_string
không còn truy cập được sau khi gọi đến +
.
Điều gì sẽ xảy ra nếu chúng ta muốn tạo ra một chuỗi mới, khiến cả hai không bị ảnh hưởng? Cách đơn giản nhất là sử dụng format!
:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Lưu ý rằng cả hai biến đầu vào là bất biến, vì vậy chúng tôi biết rằng chúng không bị chạm. Nếu chúng tôi muốn làm điều tương tự cho bất kỳ sự kết hợp nào String
, chúng tôi có thể sử dụng thực tế String
cũng có thể được định dạng:
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);
}
Bạn không cần phải sử dụng format!
mặc dù. Bạn có thể sao chép một chuỗi và nối chuỗi khác vào chuỗi mới:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Lưu ý - tất cả các đặc tả loại tôi đã làm là dư thừa - trình biên dịch có thể suy ra tất cả các loại đang chơi ở đây. Tôi đã thêm chúng đơn giản để rõ ràng với những người mới biết đến Rust, vì tôi hy vọng câu hỏi này sẽ phổ biến với nhóm đó!
Add
/ +
biểu tượng? Bạn có thể che nó nếu bạn muốn.
.to_owned()
và .to_string()
đã được khắc phục kể từ khi nhận xét ở trên nhờ chuyên môn hóa. Bây giờ cả hai đều có hiệu suất như nhau khi được gọi trên a &str
. Cam kết có liên quan: github.com/rust-lang/rust/pull/32586/files
Để nối nhiều chuỗi thành một chuỗi, cách nhau bởi một ký tự khác, có một vài cách.
Điều tốt nhất tôi đã thấy là sử dụng join
phương thức trên một mảng:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
Tùy thuộc vào trường hợp sử dụng của bạn, bạn cũng có thể thích kiểm soát hơn:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Có một số cách thủ công hơn tôi đã thấy, một số cách tránh một hoặc hai phân bổ ở đây và ở đó. Đối với mục đích dễ đọc, tôi thấy hai điều trên là đủ.
join
là thực sự gắn liền với những SliceContactExt
đặc điểm . Đặc điểm được đánh dấu là không ổn định nhưng các phương thức của nó ổn định và được bao gồm trong Prelude để chúng có thể được sử dụng ở mọi nơi theo mặc định. Nhóm nghiên cứu dường như nhận thức rõ đặc điểm này không cần tồn tại và tôi tưởng tượng mọi thứ sẽ thay đổi trong tương lai với nó.
Tôi nghĩ rằng concat
phương pháp đó và +
cũng nên được đề cập ở đây:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
và cũng có concat!
macro nhưng chỉ dành cho chữ:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+
đã được đề cập trong một câu trả lời hiện có . ( Đây là cách thực hiện Add
đặc điểm lấy String
bên trái và bên phải &str
làm bên phải :)
Có nhiều phương thức khác nhau có sẵn trong RUST để nối chuỗi
concat!()
):fn main() {
println!("{}", concat!("a", "b"))
}
Đầu ra của đoạn mã trên là:
ab
push_str()
và +
toán tử):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);
}
Đầu ra của đoạn mã trên là:
ab
abc
Using format!()
):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
Đầu ra của đoạn mã trên là:
ab
kiểm tra và thử nghiệm với sân chơi Rust
str
và&str
là các loại khác nhau và trong 99% thời gian, bạn chỉ nên quan tâm&str
. Có những câu hỏi khác chi tiết về sự khác biệt giữa chúng.