所以,如果我退回这个
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)
}
答案 0 :(得分:0)
将示例扩展到最低限度:
struct A {
string_ref: Option<NonNull<String>>,
}
impl A {
fn give_me_string(&self) -> String {
unsafe {
*self.string_ref.unwrap().as_ref()
}
}
}
这里有一些错误:
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`!")
}
}
}
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
来构成String::from
,但并未将其值存储在任何地方,而是立即转换为指针。这将在行尾释放String
,从而导致UB
。
答案 1 :(得分:0)
因此,由于有了@Optimistic Peach,我基本上就知道了发生了什么事
Unspecified error..