แปลง Vec <Vec <u8>> เป็น & [& [u8]] [ซ้ำ]
ฉันมีฟังก์ชั่นที่ใช้จำนวนของสตริงไบต์บาง: แต่ต้องการที่จะเรียกว่ามีข้อโต้แย้งของพิมพ์&[&[u8]] Vec<Vec<u8>>การเรียกใช้ฟังก์ชันดังนี้:
let foo: Vec<Vec<u8>> = Vec::new();
bar(&foo[..]);
แปลงfooเป็นชิ้น แต่ไม่ใช่ค่าที่มีอยู่ มีวิธีการแปลงนี้อย่างง่ายดายและมีประสิทธิภาพหรือไม่? หรือฉันสามารถเปลี่ยนประเภทของอาร์กิวเมนต์ของฟังก์ชันเพื่อหลีกเลี่ยงกรณีเช่นนี้ได้หรือไม่
คำตอบ
วิธีหนึ่งในการจัดการกรณีนี้โดยไม่ต้องจัดสรรเพิ่มเติมVecคือใช้AsRef<[u8]>:
fn bar<S: AsRef<[u8]>>(args: &[S]) {
// ...
}
ภายในฟังก์ชันคุณสามารถใช้.as_ref()เพื่อแปลงอาร์กิวเมนต์แต่ละรายการเป็น&[u8]ไฟล์.
( สนามเด็กเล่น )
จากมุมมองของความทรงจำสิ่งนี้ไม่สมเหตุสมผลเท่าไหร่ ในการสร้างชิ้นส่วนข้อมูลที่ถูกแบ่งจะต้องมีอยู่ในหน่วยความจำก่อน อย่างไรก็ตามในการแบ่งส่วน&[u8]ก่อนอื่นคุณต้องมีโครงสร้างข้อมูลที่ต้องการVec<&[u8]>นำชิ้นส่วนมา
กล่าวอีกนัยหนึ่งในการทำเช่นนี้คุณต้องจัดสรรพื้นที่สำหรับVec<&[u8]>หรือ[&[u8]; N]และเติมด้วยชิ้นส่วนก่อน สิ่งนี้ค่อนข้างเอาชนะจุดประสงค์ของการใช้ชิ้นส่วนเนื่องจากชิ้นส่วนนั้นหมายถึงหน่วยความจำอ้างอิงที่มีอยู่ในสถานที่ ลองใช้&[Vec<u8>]สำหรับฟังก์ชันของคุณแทน
หากการแบ่งส่วนในชั้นที่สองมีความสำคัญหรือคุณไม่สามารถแก้ไขฟังก์ชันได้คุณสามารถทำสิ่งต่อไปนี้เพื่อแปลงVec<Vec<u8>>เป็น&[&[u8]]:
let foo: Vec<Vec<u8>> = Vec::new();
// Allocate Vec of references to slices
let tmp: Vec<&[u8]> = foo.iter().map(|x| &x[..]).collect();
// Take slice of temporary Vec
bar(&tmp[..]);