gpt4 book ai didi

rust - 当 ref 和所有权转移都不起作用时如何返回

转载 作者:行者123 更新时间:2023-11-29 08:28:48 24 4
gpt4 key购买 nike

所以,如果我退回这个

self.string_ref.unwrap().as_ref()

编译器会说

error[E0515]: cannot return value referencing temporary value
returns a value referencing data owned by the current function

如果我返回

*self.string_ref.unwrap().as_ref()

编译器会说

error[E0507]: cannot move out of borrowed content

这简直把我逼疯了

这是代码:(playground)

use std::ptr::NonNull;

struct A {
string_ref: Option<NonNull<String>>,
}

struct Number {
num: i32
}

impl A {
fn hello() {

}

fn give_me_string(&self) -> String {
unsafe {
*self.string_ref.unwrap().as_ref()
}
}
}

fn main() {
let a = A {
string_ref: NonNull::new(&mut String::from("hello world") as *mut String)
};
let t = a.give_me_string();
println!("{}", t)
}

最佳答案

将您的示例剥离到最低限度:

struct A {
string_ref: Option<NonNull<String>>,
}
impl A {
fn give_me_string(&self) -> String {
unsafe {
*self.string_ref.unwrap().as_ref()
}
}
}

这里有一些错误:

  1. 最明显的一个是您试图取得 self.string_ref 的所有权,即使您只是借用了 self
    要解决这个问题,您需要使用 match 语句,它允许您解构 self.string_ref 而不是使用它:
fn give_me_string(&self) -> String {
unsafe {
match self.string_ref {
Some(x) => x.as_ref(),
None => panic!("Had no `string_ref`!")
}
}
}
  1. as_ref返回 &T,因此您不能返回拥有的字符串,而是需要克隆它并然后返回拥有的字符串,或者引用它:
//Option one: Clone contents
match self.string_ref {
Some(ref x) => x.as_ref().clone(),
_ => //...
}
//Option two: Return reference.
fn give_me_string(&self) -> &str {
unsafe {
match &self.string_ref {
Some(x) => x.as_ref() as _,
_ => //...
}
}
}

为了解决评论中提到的另一个问题,您在 main 函数中有以下语句:

string_ref: NonNull::new(&mut String::from("hello world") as *mut String)

由于其性质,这将导致 UB。您正在使用 String::from 形成一个 String,但没有将其值存储在任何地方,而是立即转换为一个指针。这将释放行尾的 String,导致 UB

关于rust - 当 ref 和所有权转移都不起作用时如何返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com