Any way to make N is 0 when Option<[i32;N]> is None auto?

struct SA<const N:usize> {
    a: Option<[i32;N]>
}

fn main() {
   let a = SA{
       a:None
   };
}

Rust Playground

1 Like

Is this what you're looking for?

   let a = SA::<0>{
       a: None
   };
2 Likes

for those who are new to rust, the keyword to lookup is "turbofish" operator.

an alternative is to use a "constructor" function, which should only be implemented for SA<0> so the type inference can resolve it, something like this:

impl SA<0> {
    fn empty() -> Self {
        SA {
            a: None
        }
    }
}
fn main() {
   let a = SA::empty();
}

a variant of this approach is to use the Default trait, so you can use SA::default() if you prefer.

impl Default for SA<0> {
    fn default() -> Self {
        SA {
            a: None
        }
    }
}
fn main() {
   let a = SA::default();
}

Instead of using the turbofish operator, it's also possible to specify the type on a like this:

fn main() {
    let a: SA<0> = SA { a: None };
}

And there’s also this slightly-obscure option:

   let a = SA{
       a: None::<[i32; 0]>
   };

Just to clarify, none of the proposed solutions enforce N==0 iff SA::a == None.

You can still have None/Some with any N.

struct SA<const N:usize> {
    a: Option<[i32;N]>
}

impl SA<0> {
    fn empty() -> Self {
        SA {
            a: None
        }
    }
}

fn main() {

   // N==0 but still has a Some
   let sa1 = SA::<0>{
       a: Some([])
   };
   
   // N!=0 but still has a None
   let sa2 = SA::<10>{
       a: None
   };

   // Produced with empty, i.e. N==0 ...
   let mut sa3 = SA::empty();
   // ... but can still be changed to have a Some
   sa3.a = Some([]);
}