การซิปเวกเตอร์ประเภทเดียวกันทำให้เกิดประเภทต่างๆภายในการปิดแผนที่
พื้นหลัง
ระบุประเภทตัวแปร enum (ไม่สามารถคัดลอกได้):
enum AstNode {
Op(Func, Box<AstNode>, Box<AstNode>),
Val(f64),
// others...
}
พยายามเรียกใช้การดำเนินการกับเวกเตอร์สองตัวดังกล่าว:
fn apply_func_iterative(func: Func, lhs: Vec<AstNode>, rhs: Vec<AstNode>) -> Vec<AstNode> {
lhs.iter().zip(rhs).map(|(&l,r)| apply_func(func,l,r)).collect() // l and r are declared differently!
}
fn apply_func(func: Func, lhs: AstNode, rhs: AstNode) -> AstNode {
// magic happens here!
}
ภายในปิดที่lhs
องค์ประกอบถือว่าชนิดl: &AstNode
ในขณะที่ซิปองค์ประกอบใช้ประเภทrhs
l: AstNode
(สังเกตการประกาศที่แตกต่างกันใน tuple การปิด)
คำถาม
เหตุใดจึงเป็นเช่นนี้
มีวิธีการวนซ้ำองค์ประกอบของเวกเตอร์ตามค่าแทนการอ้างอิงหรือไม่? ดูเหมือนจะเป็นไปได้จากพฤติกรรมที่สังเกตได้ขององค์ประกอบซิป
(ในตัวอย่างนี้ความแตกต่างนี้ส่งผลให้เกิดความแปลกเล็กน้อยในการประกาศไวยากรณ์ แต่ในทางปฏิบัติฉันได้ต่อต้านตัวตรวจสอบการยืมเมื่อส่งผ่านตัวแปรอ้างอิงไปยังฟังก์ชัน)
คำเตือน: ฉันค่อนข้างใหม่กับ Rust
คำตอบ
Iterator::zipวิธีการที่ไม่ได้ทำอะไรพิเศษก็เป็นเพียงการรวมทั้ง iterators คุณพบว่าlhs.iter()
ผลตอบแทนIterator<&AstNode>
while rhs
ให้ผลIterator<AstNode>
( &
vs non- &
)
มีวิธีการวนซ้ำองค์ประกอบของเวกเตอร์ตามค่าแทนการอ้างอิงหรือไม่? ดูเหมือนจะเป็นไปได้จากพฤติกรรมที่สังเกตได้ขององค์ประกอบซิป
ใช่มีวิธีควบคุมพฤติกรรมนี้ กุญแจสำคัญคือการสังเกตว่าzip()
อาร์กิวเมนต์rhs
ต้องใช้IntoIterator
ลักษณะ ในทางโต้ตอบzip()
จะเรียกrhs.into_iter()
เพื่อรับตัววนซ้ำจากมัน พฤติกรรมทั่วไปคือ.iter()เพียงยืมแหล่งที่มาดังนั้นจึงสามารถให้การอ้างอิงถึงค่าของมันเท่านั้น ในขณะที่บริโภคหรือ"เป็นเจ้าของ"แหล่งที่มาและสามารถให้มูลค่าที่เป็นเจ้าของได้.into_iter()
รวมเหล่านั้นที่คุณสามารถทำได้lhs.into_iter().zip(rhs)
เพื่อให้ได้ iterator กว่าค่า(AstNode, AstNode)
หรือการใช้งานlhs.iter().zip(rhs.iter())
ที่จะได้รับมากกว่า iterator (&AstNode, &AstNode)
อ้างอิง