gpt4 book ai didi

rust - 我如何告诉编译器不要评估参数?

转载 作者:行者123 更新时间:2023-11-29 07:57:09 25 4
gpt4 key购买 nike

我想指示 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{});
}

在这里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);

然后,由实现来评估 F或不,如果没有评估,则不执行任何操作。

注意:如果您不想要通用的 check , 你可以拿Box<FnOnce() -> bool>作为论点;然而,它将需要堆分配...就像在 Haskell 中一样。


让我们看一些代码! Playground link

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{});
}

关于rust - 我如何告诉编译器不要评估参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56304503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com