จะวนซ้ำอาร์เรย์ของจำนวนเต็มได้อย่างไร

ฉันจะทำอย่างไรเพื่อวนซ้ำอาร์เรย์จำนวนเต็มใน Rust

fn main () {

    let mut array: Vec<i64> = vec![2];

    for k in range(3, 13195) {
        for p in array.iter() {
           if (k % p != 0) {array.push(p)};
        }        
    }
}

ให้ฉันข้อผิดพลาดของคอมไพเลอร์:

rustc "Task2_minimalcode.rs" (ในเวอร์ชัน: C:\Users\XXX\Documents\Rust - Project Euler)

Task2_minimalcode.rs:7:14: 7:15 ข้อผิดพลาด: ประเภทที่ไม่ตรงกัน: คาดหวัง _ พบ &i64 (ตัวแปรอินทิกรัลที่คาดหวัง พบ &-ptr) [E0308] Task2_minimalcode.rs:7 if (k % p != 0) {array .push(p)};
^ Task2_minimalcode.rs:7:34: 7:35 ข้อผิดพลาด: ประเภทที่ไม่ตรงกัน: คาดว่า i64, พบ &i64 (คาดหวัง i64, พบ &-ptr) [E0308]

Task2_minimalcode.rs:7 ถ้า (k % p != 0) {array.push(p)}; ^ ข้อผิดพลาด: ยกเลิกเนื่องจากข้อผิดพลาด 2 ก่อนหน้านี้ การรวบรวมล้มเหลว


person Vega    schedule 07.02.2015    source แหล่งที่มา


คำตอบ (2)


Quoth ข้อความแสดงข้อผิดพลาด:

error: mismatched types: expected i64, found &i64 (expected i64, found &-ptr)

Vec<T>::iter ให้ตัววนซ้ำแก่คุณมากกว่า &T (อ้างอิงถึง T) หากคุณไม่ต้องการใช้ vec อีก คุณสามารถใช้ for p in array หรือ for p in array.into_iter() หากคุณ ต้องการ ต้องการใช้อีกครั้ง คุณมีหลายทางเลือก:

  • &array หรือ array.iter() และขอแสดงความนับถือ p เมื่อใช้งาน
  • array.iter().cloned()
  • array.iter().map(|e| *e) (มีผลเหมือนกับข้างบน)

หากการพูดถึงการอ้างอิงทั้งหมดนี้ไม่สมเหตุสมผล คุณควรอ่านส่วนของ Rust จองพอยน์เตอร์

โปรดจำไว้ว่าคุณสามารถหลอกให้คอมไพลเลอร์บอกประเภทของตัวแปรได้ เช่น: let _:() = p; -- ข้อความแสดงข้อผิดพลาดจะมีประเภทที่แท้จริง

person DK.    schedule 07.02.2015
comment
ฉันต้องการเวกเตอร์นั้นอีกครั้ง การอ้างอิง p เมื่อใช้มัน ฉันจะทำอย่างไร? &p ไม่ทำงาน - person Vega; 07.02.2015
comment
&p ใช้การอ้างอิงถึง p, *p ยกเลิกการอ้างอิง p คุณควรอ่านหนังสือ Rust Book จนจบ; คุณจะไปได้ไม่ไกลหากไม่เข้าใจการอ้างอิงใน Rust: มีอยู่ทุกหนทุกแห่ง - person DK.; 07.02.2015
comment
ฉันรู้ว่าการอ้างอิง/การลบล้างคืออะไร แต่มาจากโค้ดที่ได้รับการจัดการ (Java) ฉันมีเวลาที่ยากลำบากในการตัดสินใจว่าจะใช้เมื่อใดและที่ไหน :( - person Vega; 07.02.2015
comment
ด้วยเหตุนี้ฉันจึงแนะนำหนังสือเล่มนี้ มันไม่เกี่ยวกับการรู้ว่ามันคืออะไรในนามธรรม คุณต้องเข้าใจว่ามันถูกใช้อย่างไร - person DK.; 07.02.2015

เมื่อคุณวนซ้ำชิ้นส่วน (ซึ่งเป็นมุมมองใน Vec) คุณจะได้รับการอ้างอิงไปยังรายการในเวกเตอร์ ไม่ใช่รายการเอง

คุณสามารถแก้ไขได้ด้วยสองวิธีที่เทียบเท่ากัน

// Mark the iteration variable as a reference
for &p in &array {
    if (k % p != 0) {
        array.push(p)
    };
}

// Dereference the iteration variable
for p in &array {
    if (k % *p != 0) {
        array.push(*p)
    };
}

อย่างไรก็ตาม คุณจะพบกับปัญหาถัดไป: คุณไม่สามารถแก้ไข Vec ในขณะที่คุณกำลังวนซ้ำได้! หากคุณได้รับอนุญาต เวกเตอร์อาจจำเป็นต้องจัดสรรหน่วยความจำที่สนับสนุนใหม่ ซึ่งจะทำให้ การอ้างอิงทั้งหมดในตัววนซ้ำเป็นโมฆะ นี่คือจุดขายที่แข็งแกร่งของ Rust - มันป้องกันไม่ให้คุณยิงตัวเองด้วยเท้าแบบนี้!

โดยไม่รู้ว่าคุณต้องการทำอะไรจริงๆ นี่เป็นวิธีหนึ่งที่จะทำ:

fn main() {
    let input_array = vec![2u64];
    let mut output_array = input_array.clone();

    for k in 3..13195 {
        for &p in &input_array {
            if k % p != 0 {
                output_array.push(p)
            };
        }
    }
}

ดูสิ่งนี้ด้วย:

person Shepmaster    schedule 07.02.2015
comment
เป้าหมายของฉันคืองานโครงการออยเลอร์ 3 (projecteuler.net/problem=3) แต่ดูเหมือนว่าฉันต้องการ เพื่อให้ได้อัลกอริธึมที่ดีขึ้น ฉันจะคิดมากเกี่ยวกับโปรแกรมของฉัน ขอบคุณสำหรับความช่วยเหลือของคุณ :) - person Vega; 07.02.2015
comment
เท่าที่ฉันเข้าใจ สไลซ์จะให้ค่าประเภท i32 ถูกต้องหรือไม่ ฉันต้องการส่วนแบ่งของค่า usize จะระบุได้อย่างไร - person Artyom Gevorgyan; 01.08.2020
comment
@ArtemHevorhian ชิ้นส่งคืนค่าประเภทใดก็ตาม ในกรณีนี้ คือ Vec<u64> ดังนั้นส่วนย่อยและค่าที่จัดทำดัชนีจะใช้ u64 ด้วย เปลี่ยนประเภทของสไลซ์ของคุณเพื่อเปลี่ยนชิ้นส่วนย่อยและค่าที่จัดทำดัชนี - person Shepmaster; 03.08.2020