当前位置: 首页 > 知识库问答 >
问题:

错误原因:错误[E0614]:无法取消引用类型“str”

须彭亮
2023-03-14

我对 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 修饰符 2(mut ptr: Box) -

2)在fn修改器3中的注释行中,即**ptr=**ptr.to_uppercase();,导致错误“错误[E0614]: typestr不能被取消引用”,而我可以在fn修改器2中执行相同的大写()?

感谢您的任何帮助。

编辑:如果我像这样更改修饰符3():

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

这里有点混淆了的用法

谢谢

共有1个答案

何乐
2023-03-14

你的第一个问题已经在这里得到了回答,所以我会长话短说。实际上,这意味着该函数需要一个Box

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

这就是**ptr.to_uppercase()的情况ptr自动排序为str,然后通过该方法生成一个新的字符串(请参见to_uppercase上的类型签名)。

然后,您尝试引用此字符串两次。第一个 deref 导致 str,但第二个 deref 失败并出现错误[E0614]:无法取消引用类型 'str'。您可能会混淆此处的操作顺序。**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警告。从一些提示中查看此问题。

 类似资料:
  • 问题内容: 在关于sqlite的android vogella教程期间,我遇到了令人讨厌的问题,并出现以下错误: 我无数次地一步步修改所有文件,以正确重新创建R. class。关于此错误的非常奇怪的是,我不知道为什么在“ com.example.de.vogella.android”中有关于“ com.example”的任何内容。这是某种标准生成的名称吗?我所有的包/名称/路径都从未以“ com.

  • 我收到错误: 错误类型错误: 无法读取在评估 (webpack-internal:///./node_modules/@angular/common/esm5/http.js:163) 处未定义的属性 “长度”在 Array.forEach () 在 httpHeaders.lazyInit (webpack-internal:///./node_modules/@angular/common/e

  • 问题内容: 在下面的代码中,我有int无法取消引用错误,这里//我有错误。我很困惑,因为变量b用于稍后在行中引用empl数组中的点,而没有显示为错误。那么,如何解决此问题,为什么会产生错误?我将不胜感激任何帮助。示例代码也很棒,因为这似乎是我学得最好的方法。谢谢! 编辑:欢迎按员工编号对数组进行排序的任何其他建议。 问题答案: 显然会传回。 是原始类型,而不是对象。 因此,您不能调用类似的方法。

  • MAC OSX 我在“$home/documents/personal_documents/java”中有java源文件。java。 null > /usr/libexec/java_home /users/rishabshinghal/library/java/javavirtualmachines/openjdk-14.0.1/contents/home 尝试显式设置JAVA_HOME,PAT

  • 我试图使一个对话框弹出每当我得到一个错误从myerrorhandler我可以看到调用,但不是 这是我的错误消息。 错误类型错误:无法读取未定义的属性'openDialogTEST' 奇怪的是,如果我用按钮调用它,一切都很好。这是我的课程: usertable.component.ts auth.service.ts myerrorHandle.ts 对话框.component.ts 完整错误消息:

  • 问题内容: 我正在使用hibernate插入到所有表均定义为非null的mysql表中。它有一个唯一的主键,并在几列上有另一个唯一的索引。 我收到以下错误: org.springframework.dao.DataIntegrityViolationException:无法执行JDBC批处理更新。SQL [插入MY_TABLE(col1,col2,col3,col4,ID_)值(?,?,?,?,?