【问题标题】:Why the error: error[E0614]: type `str` cannot be dereferenced为什么错误:error[E0614]: type `str` cannot be dereferenced
【发布时间】:2020-03-29 07:10:22
【问题描述】:

我对 Rust 很陌生,所以这很可能是一个愚蠢的问题。

我有几个问题。

我有这两个功能:

fn modifier2(mut ptr: Box<String>) -> Box<String> {
    println!("In modifier2...");
    println!("Ptr points to {:p}, and value is {}", ptr, *ptr);

    *ptr = ptr.to_uppercase();

    println!("Exit modifier2...");
    ptr
}

fn modifier3(ptr: &mut Box<String>)  {

    println!("In modifier3...");
    println!("Ptr points to {:p}, and value is {}", ptr, *ptr);
    println!("Ptr points to {:p}, and value is {}", *ptr, **ptr);

    **ptr = "another".to_uppercase();

    //**ptr = **ptr.to_uppercase(); //error[E0614]: type `str` cannot be dereferenced

    println!("Exit modifier3...");
}

我这样称呼他们:

let mut answer = Box::new("Hello World".to_string());    
answer = modifier2(answer);
println!("called modifier2(): {} length: {}", answer, answer.len());

let mut answer = Box::new("Hello World".to_string());    
modifier3(&mut answer);
println!("called modifier3(): {} length: {}", answer, answer.len());

结果如下,我觉得很好:

In modifier2...
Ptr points to 0x2145fa1d990, and value is Hello World
Exit modifier2...
called modifier2(): HELLO WORLD length: 11

In modifier3...
Ptr points to 0x50426ffb60, and value is Hello World
Ptr points to 0x2145fa1dc50, and value is Hello World
Exit modifier3...
called modifier3(): ANOTHER length: 7

我有两个问题:

1) 在 fn modifier2(mut ptr: Box) -> Box 中,将ptr设为静音有什么意义?它与 fn modifier2(ptr: mut Box) -> Box 有何不同?

2) 在 fn modifier3 的注释行中,即 **ptr = **ptr.to_uppercase();,导致错误“error[E0614]: type str cannot be dereferenced”,而我可以在 fn 修饰符2 中做同样的大写()?

感谢您的帮助。

编辑: 如果我像这样更改modifier3():

fn modifier3(&mut ptr: &mut Box<String>)  {

    println!("In modifier3...");
    println!("Ptr points to {:p}, and *PTR points to {}, and value is {}", ptr, *ptr, **ptr);

    *ptr = "another".to_uppercase(); //or **ptr = *"another".to_uppercase();   

    println!("Exit modifier3...");
}

它给出了以下错误:

error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> src\main.rs:99:5
    |
99  |     println!("Ptr points to {:p}, and *PTR points to {}, and value is {}", ptr, *ptr, **ptr);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

这里对 &mut ptr 的用法有点困惑。

谢谢。

【问题讨论】:

    标签: rust rust-cargo


    【解决方案1】:

    您的第一个问题已经回答here,所以我会保持简短。实际上,这意味着该函数按值获取 Box&lt;String&gt; 并将其绑定到可变变量。这与在函数的第一行简单地执行let mut ptr = ptr 相同。这与通过可变的reference 进行论证有很大不同。在这里,我们拥有Box&lt;String&gt;,因此我们可以根据需要进行更改。


    当您在对象上调用方法时,Rust 编译器将执行所谓的“autoderef”以准确确定要调用的方法。有关更多信息,请参阅this question。实际上,它允许我们在引用或其他类型的指针后面调用对象上的方法。

    **ptr.to_uppercase() 就是这样。 ptr 被自动引用到str,然后通过该方法生成一个新的String(参见the type signature on to_uppercase)。

    然后,您尝试取消引用此String 两次。第一个 deref 生成 str,但第二个 deref 失败并返回 error[E0614]: type `str` cannot be dereferenced。您可能会混淆这里的操作顺序。 **ptr.to_uppercase() 执行 to_uppercase,然后取消引用。要更改顺序,请使用 (**ptr).to_uppercase() (这实际上在这里有效,但因为 autoderef 会为您做这种事情,所以它是单调的)。

    要修复代码,只需删除该行上的 derefs。

    fn modifier2(mut ptr: Box<String>) -> Box<String> {
        println!("In modifier2...");
        println!("Ptr points to {:p}, and value is {}", ptr, *ptr);
    
        *ptr = ptr.to_uppercase();
    
        println!("Exit modifier2...");
        ptr
    }
    
    fn modifier3(ptr: &mut Box<String>) {
        println!("In modifier3...");
        println!("Ptr points to {:p}, and value is {}", ptr, *ptr);
        println!("Ptr points to {:p}, and value is {}", *ptr, **ptr);
    
        **ptr = "another".to_uppercase();
    
        **ptr = ptr.to_uppercase(); // No error now
    
        println!("Exit modifier3...");
    }
    
    fn main() {
        let mut answer = Box::new("Hello World".to_string());
        answer = modifier2(answer);
        println!("called modifier2(): {} length: {}", answer, answer.len());
    
        let mut answer = Box::new("Hello World".to_string());
        modifier3(&mut answer);
        println!("called modifier3(): {} length: {}", answer, answer.len());
    }
    

    (playground)

    代码有一个 Clippy 警告。从一些提示中查看this question

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 2013-09-11
      • 2019-10-04
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      相关资源
      最近更新 更多