You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中兼容自有和引用型可迭代对象的惯用方法

解决方案:借助Borrow trait实现通用的求和函数

要让foo同时支持&i32和i32类型的迭代器,可以通过std::borrow::Borrow trait来抽象这两种类型的共性——它们都能提供一个&i32的引用。

修改后的foo函数

use std::borrow::Borrow;

fn foo<I>(it: I) -> i32
where
    I: IntoIterator,
    I::Item: Borrow<i32>,
{
    it.into_iter().map(|item| *item.borrow()).sum()
}

原理说明

  • 对于&i32类型:Borrow<i32>会直接返回自身,解引用后就是原始的i32值;
  • 对于i32类型:Borrow<i32>会返回&self,解引用后同样得到i32值。

这样无论传入的是&Vec<i32>(其迭代器Item为&i32),还是转换后的迭代器(Item为i32),都能被foo正确处理。

完整可运行代码

use std::borrow::Borrow;

fn main() {
    let v: Vec<i32> = vec![1, 2, 3];
    // 原调用正常工作
    println!("{}", foo(&v));

    let vs: Vec<&str> = vec!["1", "2", "3"];
    let converting_iterator = vs.iter().map(|s| s.parse::<i32>().unwrap());
    // 现在这个调用也能正常运行
    println!("{}", foo(converting_iterator));
}

fn foo<I>(it: I) -> i32
where
    I: IntoIterator,
    I::Item: Borrow<i32>,
{
    it.into_iter().map(|item| *item.borrow()).sum()
}

替代方案:使用AsRef trait

也可以用AsRef<i32>替代Borrow<i32>,两者效果几乎一致,修改后的约束和实现如下:

use std::convert::AsRef;

fn foo<I>(it: I) -> i32
where
    I: IntoIterator,
    I::Item: AsRef<i32>,
{
    it.into_iter().map(|item| *item.as_ref()).sum()
}

内容的提问来源于stack exchange,提问作者cadolphs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:45:21