Reputation: 3243
I know it is possible to return different types based off a const generic e.g. fn example<const N:usize>() -> [u8;N]
.
Is it possible to return generic types based off a const generic e.g. fn example<const N:usize>() -> N::Type
?
My best attempt at the moment (playground):
struct MyStruct {
first: First,
second: Second,
third: Third
}
impl MyStruct {
fn first(&self) -> &First {
&self.first
}
fn second(&self) -> &Second {
&self.second
}
fn third(&self) -> &Third {
&self.third
}
}
#[derive(Debug)]
struct First(u16);
#[derive(Debug)]
struct Second(u8);
#[derive(Debug)]
struct Third(u32);
trait ConstIndex<const INDEX:usize> {
type Output;
fn index(&self) -> &Self::Output;
}
impl ConstIndex<0> for MyStruct {
type Output = First;
fn index(&self) -> &Self::Output {
self.first()
}
}
impl ConstIndex<1> for MyStruct {
type Output = Second;
fn index(&self) -> &Self::Output {
self.second()
}
}
impl ConstIndex<2> for MyStruct {
type Output = Third;
fn index(&self) -> &Self::Output {
self.third()
}
}
fn main() {
let my_struct = MyStruct { first: First(123), second: Second(242), third: Third(789) };
let one = ConstIndex::<0>::index(&my_struct);
println!("one: {:?}",one);
let two = ConstIndex::<1>::index(&my_struct);
println!("two: {:?}",two);
let three = ConstIndex::<2>::index(&my_struct);
println!("three: {:?}",three);
}
The syntax here for indexing is awkward e.g. ConstIndex::<2>::index(&my_struct)
.
It would be preferable to use syntax like my_struct.cindex::<0>()
.
Upvotes: 1
Views: 46
Reputation: 35983
I think you're looking for something like this:
struct MyStruct {
first: First,
second: Second,
third: Third
}
impl MyStruct {
fn first(&self) -> &First {
&self.first
}
fn second(&self) -> &Second {
&self.second
}
fn third(&self) -> &Third {
&self.third
}
fn cindex<const N:usize>(&self) -> &<MyStruct as ConstIndex<N>>::Output
where MyStruct : ConstIndex<N>
{
<MyStruct as ConstIndex<N>>::index(self)
}
}
#[derive(Debug)]
struct First(u16);
#[derive(Debug)]
struct Second(u8);
#[derive(Debug)]
struct Third(u32);
trait ConstIndex<const INDEX:usize> {
type Output;
fn index(&self) -> &Self::Output;
}
impl ConstIndex<0> for MyStruct {
type Output = First;
fn index(&self) -> &Self::Output {
self.first()
}
}
impl ConstIndex<1> for MyStruct {
type Output = Second;
fn index(&self) -> &Self::Output {
self.second()
}
}
impl ConstIndex<2> for MyStruct {
type Output = Third;
fn index(&self) -> &Self::Output {
self.third()
}
}
fn main() {
let my_struct = MyStruct { first: First(123), second: Second(242), third: Third(789) };
let one = ConstIndex::<0>::index(&my_struct);
println!("one: {:?}",one);
let two = ConstIndex::<1>::index(&my_struct);
println!("two: {:?}",two);
let three = ConstIndex::<2>::index(&my_struct);
println!("three: {:?}",three);
let one_2 = my_struct.cindex::<0>();
println!("one: {:?}",one_2);
let two_2 = my_struct.cindex::<1>();
let three_2 = my_struct.cindex::<2>();
}
Upvotes: 1