Why would struct initialization order matter?

I have this code:

struct Chunk{
    chunk_type: ChunkType,
    data: Vec<u8>,
    crc: u32
}

impl Chunk {
    fn new(chunk_type: ChunkType, data: Vec<u8>) -> Self {
        let crc = Crc::<u32>::new(&CRC_32_CKSUM);

        Chunk {
            crc: crc.checksum(&[&chunk_type.bytes()[..], &data].concat()),
            chunk_type,
            data
        }
    }
}

It compiles just fine. However, if I just change the order of params in the initialization of Chunk, I get the classic "borrow of a moved value" error:

impl Chunk {
    fn new(chunk_type: ChunkType, data: Vec<u8>) -> Self {
        let crc = Crc::<u32>::new(&CRC_32_CKSUM);

        Chunk {
            chunk_type, // value moved here
            data,
            crc: crc.checksum(&[&chunk_type.bytes()[..], &data].concat()) // borrow of moved value
        }
    }
}

I wonder, why would it throw such an error in this case? Won't the value of crc property be calculated before any move occurs?

No. Initializer expressions are evaluated in order, top down. The move of chunk_type happens before the checksum call.

1 Like

It makes sense, I just expected the compiler to reorder the calls when the order wouldn't matter, but probably I expected too much.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.