< 返回版块

hzqd 发表于 2020-09-10 15:28

Tags:trait,fn,extension

我想对 Vec<T> 实现一个 .on_each() 扩展函数(该函数在 Kotlin、JavaScript 标准库中均有实现)如果您不知道该函数的功能是什么,可参考:这篇博客 中“新的数组函数”章节。下面是我的代码(已修改至编译通过):

// 首先定义一个可以返回自身的函数,参考了 Kotlin 的扩展函数 also
trait KtStd {
    fn also_ref(&self, block: impl FnOnce(&Self)) -> &Self {
        block(self);
        self
    }
}
// 任意类型都可点出该函数
impl<T> KtStd for T {}

// 然后是 on_each() 的实现
trait IterExt<T> {
    fn on_each(&self, f: impl Fn(&T)) -> &Self;
}

impl<T> IterExt<T> for Vec<T> {
    fn on_each(&self, f: impl Fn(&T)) -> &Self {
        self.also_ref(|v| v.iter().for_each(|e| f(e)))
    }
}

有人指出这 on_each() 没有组合性,也就是不能 .map().on_each().filter(),需要先 .collect().on_each().iter();但我认为,既然标准库已经有了 inspect 函数,那这 on_each 函数就当作某种特殊情况(前后都不需要组合)来用吧。

评论区

写评论
Neutron3529 2020-09-11 01:13

好像oneach的意思是,可以对数组进行改变

我刚刚试了试iter_mut跟inspect很难同时使用

--
👇
laizy: 你要的是迭代器的inspect函数: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.inspect

laizy 2020-09-10 18:15

你要的是迭代器的inspect函数: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.inspect

Neutron3529 2020-09-10 16:44

直接map不香吗?

fn change(i:&mut i32){*i+=123}
fn main(){
    let mut v=vec![1,2,3,4,5];
    dbg!(v.iter_mut().map(|i|{let z=*i;change(i);z}).collect::<Vec<i32>>());
    dbg!(v);
}

执行结果

Standard Error

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.57s
     Running `target/debug/playground`
[src/main.rs:5] v.iter_mut().map(|i| { let z = *i; change(i); z }).collect::<Vec<i32>>() = [
    1,
    2,
    3,
    4,
    5,
]
[src/main.rs:6] v = [
    124,
    125,
    126,
    127,
    128,
]
1 共 3 条评论, 1 页