我想指示Rust编译器在任何情况下都不求值。这是一个例子:
#![allow(dead_code)]
trait CheckTrait {
    fn check(b : bool);
}
struct CheckStructA {}
struct CheckStructB {}
impl CheckTrait for CheckStructA {
    fn check(_b : bool) {
        println!("CheckStructA");
    }
}
impl CheckTrait for CheckStructB {
    // compiler: do not evaluate the argument _b
    fn check(_b : bool) {
    }
}
fn show_stuff_a() -> bool {
    println!("Show stuff A");
    true
}
fn show_stuff_b() -> bool {
    println!("Show stuff B");
    true
}
fn test_a<T : CheckTrait>(_ : T) {
    T::check(show_stuff_a());
}
fn test_b<T : CheckTrait>(_ : T) {
    T::check(show_stuff_b());
}
fn main() {
    test_a(CheckStructA{});
    test_b(CheckStructB{});
 }
Run Code Online (Sandbox Code Playgroud)
这CheckStructB实际上是的禁用版本CheckStructA。凡评论是,我希望能够指示编译器不评价任何表达式计算_b的CheckStructB::check,但仍评估任何表达式将计算_b的CheckStructA::check。此代码的结果是,它将仍然向控制台输出“ Show Stuff A”,但不会向控制台输出“ Show Stuff B”。
在C#中,可以通过使用[System.Diagnostics.Conditional(“ DoNotEverTurnThisOn”)]替换注释来完成此操作。我不想在宏中定义类型,因为这会破坏智能感知。
如何在Rust中完成?
仅根据需要评估参数称为“惰性评估”。
在像Haskell这样的语言(默认为“懒惰求值”)中,类型的参数或变量bool实际上并不表示为bool立即数,而是表示为“ thunk”,其中包含调用函数和自己的参数(可能是thunk) 。
在Rust中,由于默认为Eager Evaluation,因此您需要以参数类型或有价值的类型显式表示惰性。通常,通过不要求T而是要求FnOnce() -> T来完成。
因此,您将重写check为:
fn check<F: FnOnce() -> bool>(condition: F);
Run Code Online (Sandbox Code Playgroud)
然后,由实施来评估F或不评估,如果不评估,则不执行任何操作。
注意:如果您不想使用泛型check,可以将其Box<FnOnce() -> bool>作为参数;但是,它将需要堆分配...就像在Haskell中一样。
让我们看一些代码!游乐场链接
trait CheckTrait {
    fn check<F: FnOnce() -> bool>(b: F);
}
struct CheckStructA {}
struct CheckStructB {}
impl CheckTrait for CheckStructA {
    fn check<F: FnOnce() -> bool>(b: F) {
        b();
        println!("CheckStructA");
    }
}
impl CheckTrait for CheckStructB {
    fn check<F: FnOnce() -> bool>(_b: F) {
        println!("CheckStructB");
    }
}
fn show_stuff_a() -> bool {
    println!("Show stuff A");
    true
}
fn show_stuff_b() -> bool {
    println!("Show stuff B");
    true
}
fn test_a<T : CheckTrait>(_ : T) {
    T::check(|| show_stuff_a());
}
fn test_b<T : CheckTrait>(_ : T) {
    T::check(|| show_stuff_b());
}
fn main() {
    test_a(CheckStructA{});
    test_b(CheckStructB{});
}
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           76 次  |  
        
|   最近记录:  |