为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不允许引用字符串(&String)、Vec(&Vec)或Box(&Box)作为函数参数?

为什么不允许引用字符串(&String)、Vec(&Vec)或Box(&Box)作为函数参数?

温温酱 2019-06-06 10:37:42
为什么不允许引用字符串(&String)、Vec(&Vec)或Box(&Box)作为函数参数?我编写了一些锈蚀代码&String作为论据:fn awesome_greeting(name: &String) {     println!("Wow, you are awesome, {}!", name);}我还编写了代码,其中引用了Vec或Box:fn total_price(prices: &Vec<i32>) -> i32 {     prices.iter().sum()}fn is_even(value: &Box<i32>) -> bool {     **value % 2 == 0}然而,我收到一些反馈说,这样做不是一个好主意。为什么不行?
查看完整描述

2 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

我们可以用&str&[T]&T以允许使用更通用的代码。


  1. 使用String或者是Vec是因为他们允许增加或减少容量。但是,当您接受不可变引用时,您不能在VecString.

  2. 接受&String&Vec&Box要求在调用函数之前要在堆上分配的参数。接受&str允许字符串文本(保存在程序数据中)并接受&[T]&T允许堆栈分配的数组或变量。不必要的分配是一种性能损失。在尝试在测试中调用这些方法时,通常会立即公开这些方法。main方法:

    awesome_greeting(&String::from("Anna"));
    total_price(&vec![42, 13, 1337])
    is_even(&Box::new(42))
  3. 另一个性能考虑是&String&Vec&Box引入不必要的间接层,因为您必须取消对&String得到一个String然后是第二次取消引用&str.

相反,您应该接受串片 (&str),a切片 (&[T]),或者仅仅是一个引用(&T)。一个&String&Vec<T>&Box<T>将被自动胁迫到&str&[T]&T分别。

fn awesome_greeting(name: &str) {
    println!("Wow, you are awesome, {}!", name);}
fn total_price(prices: &[i32]) -> i32 {
    prices.iter().sum()}
fn is_even(value: &i32) -> bool {
    *value % 2 == 0}

现在,您可以使用更广泛的类型集来调用这些方法。例如,awesome_greeting可以用字符串文字调用("Anna"分配Stringtotal_price可以通过对数组的引用调用(&[1, 2, 3]分配Vec.


如果要从StringVec<T>,你可以可变参考 (&mut String&mut Vec<T>):

fn add_greeting_target(greeting: &mut String) {
    greeting.push_str("world!");}
fn add_candy_prices(prices: &mut Vec<i32>) {
    prices.push(5);
    prices.push(25);}

特别是对于片,您也可以接受&mut [T]&mut str..这允许您在片内变异一个特定的值,但不能更改片内的项目数(这意味着它对字符串非常有限):

fn reset_first_price(prices: &mut [i32]) {
    prices[0] = 0;}
fn lowercase_first_ascii_character(s: &mut str) {
    if let Some(f) = s.get_mut(0..1) {
        f.make_ascii_lowercase();
    }}


查看完整回答
反对 回复 2019-06-06
  • 2 回答
  • 0 关注
  • 639 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信