Rust中对Vec引用调用reduce方法计算均值报编译错误如何解决?
问题核心原因
你对iter()的基础理解是对的:integers.iter()返回的迭代器产出的是&i32类型的元素,reduce方法要求闭包的输入、输出类型必须和迭代器产出的类型完全一致,也就是此处必须返回&i32类型。
你写的|&a, &b是Rust的模式匹配解构语法:相当于把传进来的两个&i32引用直接解引用,拿到了a、b两个i32类型的原值。你计算a + b得到的是一个临时的i32值,这个值存放在当前闭包的栈空间里,闭包执行完就会被销毁,此时返回&(a + b)相当于返回了一个指向已经销毁数据的悬垂引用,所以编译器报E0515错误。
如果把&去掉,你返回的是i32类型,又不符合reduce要求返回&i32的规则,就会出现你遇到的“两边报错”的死循环情况。
解决方案
方案1:用copied()转成值类型迭代器(最贴合你原来的写法)
在iter()后加copied()方法,可以直接把迭代器产出的&i32转成i32原值,此时reduce就要求返回i32类型,完全不需要处理引用问题:
fn mean(integers: &Vec<i32>) -> i32 { let length = integers.len() as i32; // 加copied(),迭代器产出i32而非&i32 let sum = integers.iter().copied().reduce(|a, b| a + b); match sum { Some(v) => v / length, None => 0, } }
方案2:直接用sum()方法(求和场景更简洁)
求和场景不需要自己手写reduce逻辑,Rust迭代器内置的sum()方法天然处理引用类型的求和,代码更短:
fn mean(integers: &Vec<i32>) -> i32 { let length = integers.len() as i32; let sum: i32 = integers.iter().sum(); if length == 0 { 0 } else { sum / length } }
两种方案都不会修改你原来传引用的逻辑,后续依然可以正常使用list_of_integers变量。
内容的提问来源于stack exchange,提问作者alferguson_JS
相关产品推荐
相关产品推荐

