ฉันจะต่อชุดประเภทต่อไปนี้เข้าด้วยกันได้อย่างไร:
strและstrStringและstrStringและString
ฉันจะต่อชุดประเภทต่อไปนี้เข้าด้วยกันได้อย่างไร:
str และ strString และ strString และ Stringคำตอบ:
เมื่อคุณต่อสตริงคุณต้องจัดสรรหน่วยความจำเพื่อจัดเก็บผลลัพธ์ วิธีที่ง่ายที่สุดในการเริ่มต้นคือ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 สามารถ dereferenced &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
                    ฉันคิดว่า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"))
}
ผลลัพธ์ของรหัสข้างต้นคือ:
AB
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);
}
ผลลัพธ์ของรหัสข้างต้นคือ:
AB
abc
Using format!()):fn main() {
    let mut _a = "a".to_string();
    let _b = "b".to_string();
    let _c = format!("{}{}", _a, _b);
    
    println!("{}", _c);
}
ผลลัพธ์ของรหัสข้างต้นคือ:
AB
ลองดูและทดลองเล่นกับRust play ground
strและ&strเป็นชนิดที่แตกต่างกันและสำหรับ 99%&strของเวลาที่คุณควรดูแลเกี่ยวกับ มีคำถามอื่น ๆ ที่แสดงรายละเอียดความแตกต่างระหว่างพวกเขา