等效于`std :: iter :: Inspect`方法链

发布于 2025-02-12 07:25:01 字数 678 浏览 0 评论 0原文

在Rust,是否可以在方法链中检查中间值?等效方法 iterators for Iterators 在传递到链中的下一个迭代器之前,可以检查产生的值。本质上,我正在寻找类似的东西:

impl<T> T {
    fn inspect(&self, f: impl Fn(&Self)) -> &Self {
        f(&self);
        &self
    }
}

// ...

object
    .a()
    .inspect(|x| println!("after a(): {:?}", x))
    .b()
    .inspect(|x| println!("after b(): {:?}", x))
    .c();

目的是帮助调试长长的功能调用;当前,唯一的解决方案是用分配到变量,打印变量,然后继续使用链的其余部分,将链分解为变量。

这样的东西存在吗?我相信孤儿规则将禁止一般实施它。

In rust, is it possible to inspect the intermediate values in a chain of method calls? The equivalent method exists for iterators so that the values produced may be inspected before being passed to the next iterator in the chain. Essentially, I'm looking for something like this:

impl<T> T {
    fn inspect(&self, f: impl Fn(&Self)) -> &Self {
        f(&self);
        &self
    }
}

// ...

object
    .a()
    .inspect(|x| println!("after a(): {:?}", x))
    .b()
    .inspect(|x| println!("after b(): {:?}", x))
    .c();

The purpose is to aid in debugging a long chain of function calls; currently the only solution is to break up the chain with an assignment to a variable, print the variable, and then continue on with the rest of the chain.

Does something like this exist? I believe the orphan rules would forbid one from implementing it themself in general.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

与风相奔跑 2025-02-19 07:25:01

您几乎可以为此定义一个特征:

trait Inspect {
    fn inspect(self, f: impl Fn(&Self)) -> Self;
}

impl<T> Inspect for T {
    fn inspect(self, f: impl Fn(&Self)) -> Self {
        f(&self);
        self
    }
}

我对其进行了一些修改以通过值将self传递以使其更加灵活。它将与&amp; t/&amp; mut t和返回&amp; t/&amp; mut t

测试:

#[derive(Debug)]
struct Foo {}

impl Foo {
    fn a(&self) -> &Self {
        self
    }
    fn b(&self) -> &Self {
        self
    }
    fn c(&self) -> &Self {
        self
    }
}

fn main() {
    Foo {}
        .a()
        .inspect(|x| println!("after a(): {:?}", x))
        .b()
        .inspect(|x| println!("after b(): {:?}", x))
        .c();
}

输出:

after a(): Foo
after b(): Foo


测试可变值:

#[derive(Debug, Default)]
struct Foo {
    value: i32,
}

impl Foo {
    fn a(&mut self) -> &mut Self {
        self.value += 1;
        self
    }
    fn b(&mut self) -> &mut Self {
        self.value += 2;
        self
    }
}

fn main() {
    Foo::default()
        .a()
        .inspect(|x| println!("after a(): {:?}", x))
        .b()
        .inspect(|x| println!("after b(): {:?}", x));
}

输出:

after a(): Foo { value: 1 }
after b(): Foo { value: 3 }

You can define a trait for this almost exactly like that:

trait Inspect {
    fn inspect(self, f: impl Fn(&Self)) -> Self;
}

impl<T> Inspect for T {
    fn inspect(self, f: impl Fn(&Self)) -> Self {
        f(&self);
        self
    }
}

I modified it a bit to pass self by value to make it more flexible. It will work with &T/&mut T and return &T/&mut T.

Test:

#[derive(Debug)]
struct Foo {}

impl Foo {
    fn a(&self) -> &Self {
        self
    }
    fn b(&self) -> &Self {
        self
    }
    fn c(&self) -> &Self {
        self
    }
}

fn main() {
    Foo {}
        .a()
        .inspect(|x| println!("after a(): {:?}", x))
        .b()
        .inspect(|x| println!("after b(): {:?}", x))
        .c();
}

Output:

after a(): Foo
after b(): Foo

Playground


Test for mutable value:

#[derive(Debug, Default)]
struct Foo {
    value: i32,
}

impl Foo {
    fn a(&mut self) -> &mut Self {
        self.value += 1;
        self
    }
    fn b(&mut self) -> &mut Self {
        self.value += 2;
        self
    }
}

fn main() {
    Foo::default()
        .a()
        .inspect(|x| println!("after a(): {:?}", x))
        .b()
        .inspect(|x| println!("after b(): {:?}", x));
}

Output:

after a(): Foo { value: 1 }
after b(): Foo { value: 3 }

Playground

無處可尋 2025-02-19 07:25:01

There's a crate for that: tap. It provides a Tap trait with a tap() method as well as additional traits and methods for various things like mutable access, optionals and more.

Specifically for Option and Result, they also have unstable `inspect() methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文