CodeBlanks Logo Icon CodeBlanks

Min_const_generics

Learn the limits and valid uses of min_const_generics.

Stable const generics limits

In stable Rust (min_const_generics), const parameters can only be integers, bool and char. Also, expressions involving const parameters can't be used in types:

fn f<const N: usize>() -> [u8; N] { [0; N] }        // fine
// fn g<const N: usize>() -> [u8; N + 1] { .. }    // error: generic expression
// struct S<const AD: &'static str>;               // error: type not allowed

Expressions like N + 1 are only possible on nightly with the generic_const_exprs feature. In stable code the solution is usually going back to slices or converting at runtime with try_into.

From slice to array

Taking a slice's first N elements as a fixed-size array, if the length allows:

fn ilk_n<const N: usize>(v: &[i32]) -> Option<[i32; N]> {
    v.get(..N)?.try_into().ok()
}

println!("{:?}", ilk_n::<2>(&[5, 6, 7]));   // Some([5, 6])
println!("{:?}", ilk_n::<5>(&[5, 6, 7]));   // None

get(..N) gives None out of bounds; try_into converts the slice of length N into an array.

Practice First N elements

Write the ilk_n function above. Print the results of ilk_n::<2>(&[5, 6, 7]) and ilk_n::<5>(&[5, 6, 7]) with {:?}, separated by a space.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn ilk_n<const N: usize>(v: &[i32]) -> Option<[i32; N]> {
    v.get(..N)?.try_into().ok()
}

fn main() {
    println!("{:?} {:?}", ilk_n::<2>(&[5, 6, 7]), ilk_n::<5>(&[5, 6, 7]));
}

Expected output

Some([5, 6]) None

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 How do you go from a slice to an array of a specific length?

  • as [T; N]
  • You can't
  • It needs unsafe
  • <[T; N]>::try_from(slice) or slice.try_into() Correct answer

Explanation: If the length doesn't match, Err is returned, so the runtime check stays safe.

2 Convert to an array

Question
fn ilk_n<const N: usize>(v: &[i32]) -> Option<[i32; N]> {
    v.get(..N)?.____().ok()
}
Answer
fn ilk_n<const N: usize>(v: &[i32]) -> Option<[i32; N]> {
    v.get(..N)?.try_into().ok()
}

Explanation: try_into converts the slice into an array with a length check.

3 Syntax and stable status

Term Meaning
<const N: usize> Stable
<const B: bool> Stable (bool)
[u8; N + 1] Nightly only
<const S: &str> Not supported

All lessons in Advanced