rust 为什么一个带有const泛型boolean的方法不能调用一个同时为true和false实现的方法?

9rnv2umw  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(82)

下面的代码运行得很好(playground):

struct MyStruct<const B: bool>;

impl MyStruct<false> {
    pub fn bar() {
        println!("false");
    }
}
impl MyStruct<true> {
    pub fn bar() {
        println!("true");
    }
}

impl MyStruct<false> {
    pub fn foo() {
        MyStruct::<false>::bar()
    }
}
impl MyStruct<true> {
    pub fn foo() {
        MyStruct::<true>::bar()
    }
}

fn main() {
    MyStruct::<false>::foo();
    MyStruct::<true>::foo();
}

字符串
其结果是:

false
true


另一方面,这段代码将失败(playground):

struct MyStruct<const B: bool>;

impl MyStruct<false> {
    pub fn bar() {
        println!("false");
    }
}
impl MyStruct<true> {
    pub fn bar() {
        println!("true");
    }
}

impl<const B: bool> MyStruct<B> {
    pub fn foo() {
        MyStruct::<B>::bar()
    }
}

fn main() {
    MyStruct::<false>::foo();
    MyStruct::<true>::foo();
}


导致:

error[E0599]: no function or associated item named `bar` found for struct `MyStruct<B>` in the current scope
  --> src/main.rs:16:24
   |
1  | struct MyStruct<const B: bool>;
   | ------------------------------- function or associated item `bar` not found for this
...
16 |         MyStruct::<B>::bar()
   |                        ^^^ function or associated item not found in `MyStruct<B>`
   |
   = note: the function or associated item was found for
           - `MyStruct<false>`
           - `MyStruct<true>`


我可以理解无限值类型的错误,但为什么是布尔类型呢?
有没有办法克服这一点?

nhhxz33t

nhhxz33t1#

必须使用trait和泛型类型条件(playground):

struct MyStruct<const B: bool>;

trait Bar {
    fn bar();
}

impl Bar for MyStruct<false> {
    fn bar() {
        println!("false");
    }
}
impl Bar for MyStruct<true> {
    fn bar() {
        println!("true");
    }
}

impl<const B: bool> MyStruct<B>
where
    MyStruct<B>: Bar,
{
    pub fn foo() {
        MyStruct::<B>::bar()
    }
}

fn main() {
    MyStruct::<false>::foo();
    MyStruct::<true>::foo();
}

字符串
当然,该原理可以推广到boolplayground)以外的其他类型:

struct MyStruct<const U: usize>;

trait Bar {
    fn bar();
}

impl Bar for MyStruct<0> {
    fn bar() { println!("0"); }
}
impl Bar for MyStruct<1> {
    fn bar() { println!("1"); }
}
impl Bar for MyStruct<100> {
    fn bar() { println!("100"); }
}

impl<const U: usize> MyStruct<U> where MyStruct<U> : Bar {
    pub fn foo() { MyStruct::<U>::bar() }
}

fn main() {
    MyStruct::<0>::foo();
    MyStruct::<1>::foo();
    MyStruct::<100>::foo();
}

zvms9eto

zvms9eto2#

playground

struct MyStruct<const B: bool>;

impl MyStruct<false> {
    pub fn bar() {
        println!("false");
    }
}
impl MyStruct<true> {
    pub fn bar() {
        println!("true");
    }
}

impl<const B: bool> MyStruct<B> {
    pub fn foo() {
        if B {
            MyStruct::<true>::bar()
        } else {
            MyStruct::<false>::bar()
        }
    }
}

fn main() {
    MyStruct::<false>::foo();
    MyStruct::<true>::foo();
}

字符串

相关问题