ฉันพยายามเขียนไคลเอนต์ TCP / IP อย่างง่ายใน Rust และฉันต้องการพิมพ์บัฟเฟอร์ที่ได้รับจากเซิร์ฟเวอร์
ฉันจะแปลง a Vec<u8>
(หรือ a &[u8]
) เป็น a ได้String
อย่างไร
ฉันพยายามเขียนไคลเอนต์ TCP / IP อย่างง่ายใน Rust และฉันต้องการพิมพ์บัฟเฟอร์ที่ได้รับจากเซิร์ฟเวอร์
ฉันจะแปลง a Vec<u8>
(หรือ a &[u8]
) เป็น a ได้String
อย่างไร
คำตอบ:
ในการแปลงชิ้นส่วนไบต์เป็นชิ้นสตริง (สมมติว่าเป็นการเข้ารหัส UTF-8):
use std::str;
//
// pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error>
//
// Assuming buf: &[u8]
//
fn main() {
let buf = &[0x41u8, 0x41u8, 0x42u8];
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
println!("result: {}", s);
}
การแปลงอยู่ในสถานที่และไม่จำเป็นต้องมีการจัดสรร คุณสามารถสร้างString
จากสไลซ์สตริงได้หากจำเป็นโดยเรียก.to_owned()
ใช้สไลซ์สตริง ( มีตัวเลือกอื่น ๆ )
การอ้างอิงไลบรารีสำหรับฟังก์ชันการแปลง:
from_utf8
ไม่ได้จัดสรร แต่ก็อาจคุ้มค่าที่จะกล่าวถึงว่าจำเป็นต้องสแกนข้อมูลเพื่อตรวจสอบความถูกต้องของ utf-8 ดังนั้นนี่ไม่ใช่การดำเนินการ O (1) (ซึ่งอาจคิดในตอนแรก)
ฉันชอบString::from_utf8_lossy
:
fn main() {
let buf = &[0x41u8, 0x41u8, 0x42u8];
let s = String::from_utf8_lossy(buf);
println!("result: {}", s);
}
มันเปลี่ยน UTF-8 ไบต์ที่ไม่ถูกต้องเป็น ดังนั้นจึงไม่จำเป็นต้องจัดการข้อผิดพลาด มันดีสำหรับเมื่อคุณไม่ต้องการสิ่งนั้นและฉันแทบไม่ต้องการมันเลย คุณจะได้รับString
จากสิ่งนี้จริงๆ ควรทำให้การพิมพ์สิ่งที่คุณได้รับจากเซิร์ฟเวอร์ง่ายขึ้นเล็กน้อย
บางครั้งคุณอาจต้องใช้into_owned()
วิธีนี้เนื่องจากเป็นการลอกแบบเขียน
into_owned()
คำแนะนำ! นั่นคือสิ่งที่ฉันกำลังมองหา (สิ่งนี้ทำให้มันกลายเป็นค่าที่เหมาะสมString
ซึ่งคุณสามารถส่งคืนเป็นค่าส่งคืนจากวิธีการเป็นต้น)
หากคุณมีเวกเตอร์ไบต์ ( Vec<u8>
) จริงและต้องการแปลงเป็น a String
วิธีที่มีประสิทธิภาพที่สุดคือการนำการจัดสรรกลับมาใช้ใหม่กับString::from_utf8
:
fn main() {
let bytes = vec![0x41, 0x42, 0x43];
let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
println!("{}", s);
}
Vec
เอ แต่ผู้มาใหม่ไม่รู้ความแตกต่าง อย่าลืมโหวตคำถามและคำตอบทั้งหมดที่พิสูจน์ว่ามีประโยชน์
String::from_utf8_lossy
แทนได้ที่นี่คุณไม่จำเป็นต้องโทร
String::from_utf8_lossy
แทนได้ที่นี่คุณไม่จำเป็นต้องใช้การexpect
โทร แต่ข้อมูลที่ป้อนนั้นเป็นส่วนของ bytess ( &'a [u8]
) OTOH ก็มีเช่นfrom_utf8_unchecked
กัน "ถ้าคุณแน่ใจว่าชิ้นไบต์ที่ถูกต้อง UTF-8 และคุณไม่ต้องการที่จะต้องเสียค่าใช้จ่ายของการแปลงที่มีเป็นรุ่นที่ไม่ปลอดภัยของฟังก์ชันนี้ [ from_utf8_lossy]
, from_utf8_unchecked
ซึ่งมีพฤติกรรมเดียวกัน แต่ข้ามการตรวจสอบ "
&vec_of_bytes
เพื่อแปลงกลับเป็นส่วนของไบต์ตามที่แสดงในตัวอย่างของfrom_utf8_lossy
. doc.rust-lang.org/std/string/…