繁体   English   中英

为什么会出现错误:error[E0614]: type `str` 不能被取消引用

[英]Why the error: error[E0614]: type `str` cannot be dereferenced

我对 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 修饰符 3 的注释行中,即 **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 的用法混淆。

谢谢。

你的第一个问题已经在这里回答,所以我会保持简短。 实际上,这意味着该函数按值获取Box<String>并将其绑定到可变变量。 这与在函数的第一行简单地执行let mut ptr = ptr相同。 这与通过可变引用获取参数非常不同。 在这里,我们拥有Box<String> ,因此特别是我们可以根据需要更改它。


当你在一个对象上调用一个方法时,Rust 编译器将执行所谓的“autoderef”来准确地找出要调用的方法。 有关更多信息,请参阅此问题 实际上,它允许我们在引用或其他类型的指针后面调用对象上的方法。

这就是**ptr.to_uppercase()发生的事情。 ptr被自动引用为str ,然后该方法生成一个新的String (参见to_uppercase上的类型签名)。

然后,您尝试取消引用此String两次。 第一个 deref 导致str ,但第二个失败并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());
}

(操场)

该代码有一个 Clippy 警告。 从一些提示中看到这个问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM