Yuchen
Yuchen

Reputation: 33126

Enforce the length of the arrays are the same in Rust function arguments

We have a function with two vectors. We would like to ensure that the length of the two vectors is the same. Is there a way to enforce that from the type level in Rust?

For example, here we guarantee that the two input vectors num1 and num2 are of length 4.

fn foo(nums1: [i32; 4], nums2: Vec<[i32; 4]>) {
    println!("{:?}", nums1);
    println!("{:?}", nums2);
}

What we really want is this:

fn bar(nums1: Vec<i32>, nums2: Vec<Vec<i32>>) {
    for row in &nums2 {
        assert!(nums1.len() == row.len());
    }

    println!("{:?}", nums1);
    println!("{:?}", nums2);
}

We want them to be of the same length but they can be of any length. The above works fine of cause, however, it is a runtime check instead of a compile time check.

Is there a way to achieve this in compile time with some Rust generic, macro, or whatever dark magic?

# N to be any integer larger than 1
fn baz(nums1: [i32; N], nums2: Vec<[i32; N]>) {
    println!("{:?}", nums1);
    println!("{:?}", nums2);
}

Upvotes: 3

Views: 227

Answers (1)

Tobias S.
Tobias S.

Reputation: 23905

You can use const generics.

fn foo<const N: usize>(nums1: [i32; N], nums2: Vec<[i32; N]>) {
    println!("{:?}", nums1);
    println!("{:?}", nums2);
}

fn main() {
    foo([1, 2], vec![[1, 2], [1, 2]]);
    foo([1, 2, 3], vec![[1, 2], [1, 2]]);
    //                   ^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
}

Upvotes: 5

Related Questions