Newtype pattern error: cannot move out of dereference of
Newtype pattern error: cannot move out of dereference of
我想围绕现有 type/struct 创建一个包装器。根据 Newtype 模式,根据 Rust Book ch 19,“在 Wrapper 上实现 Deref 特性到 return 内部类型将提供对所有底层方法的访问”:
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
这是我对字符串的包装器的实现。一个简化的例子:
struct Wrapper(String);
impl Deref for Wrapper {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0 //pointer to Inner value
}
}
但是,调用一个消耗 self 的方法会抛出错误:
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
w.into_bytes();
}
错误:无法从 Wrapper
的解引用中移出,因为值的类型为 std::string::String
,它没有实现 Copy
特征
因此我有两个问题:
- 我的实现有什么问题,如何让它发挥作用?
- 我想让它与 self、&self、mut self 和 &mut self 方法一起正常工作。如何适当地实施 DerefMut?
What is wrong with my implementation and how do make it work?
String::into_bytes
移动 String
,在你的情况下你只能访问它的引用 &
,所以你不能移动它。
您可以使用 bytes
其中 returns 一个字节的迭代器而不移动它:
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let b = w.bytes();
println!("{b:?}");
}
I'd like to make it work properly with self, &self, mut self, &mut self methods. How do I also implement DerefMut appropriately?
您需要考虑签名,一般来说:
Deref
-> 得到一个 &T
DerefMut
-> 得到一个 &mut
From/Into
-> 将类型转换为其他类型的拥有版本 T
示例使用 From/Into
:
struct Wrapper(String);
impl From<Wrapper> for String {
fn from(w: Wrapper) -> String {
w.0
}
}
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let s: String = w.into();
let bytes = s.into_bytes();
println!("{bytes:?}");
}
您还可以考虑查看 std::borrow
模块,它具有允许您像其他类型一样使用您的类型的特性。
最后,您的方法可能会奏效,但如前所述,在这种情况下您不能从 &T
转到 U
(您可以 T
转到 U
) .剩下的解决方案是 Clone
并创建一个拥有的副本:
use std::ops::Deref;
struct Wrapper(String);
impl Deref for Wrapper {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0 //pointer to Inner value
}
}
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let b = w.deref().clone().into_bytes();
println!("{b:?}");
}
我想围绕现有 type/struct 创建一个包装器。根据 Newtype 模式,根据 Rust Book ch 19,“在 Wrapper 上实现 Deref 特性到 return 内部类型将提供对所有底层方法的访问”:
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
这是我对字符串的包装器的实现。一个简化的例子:
struct Wrapper(String);
impl Deref for Wrapper {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0 //pointer to Inner value
}
}
但是,调用一个消耗 self 的方法会抛出错误:
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
w.into_bytes();
}
错误:无法从 Wrapper
的解引用中移出,因为值的类型为 std::string::String
,它没有实现 Copy
特征
因此我有两个问题:
- 我的实现有什么问题,如何让它发挥作用?
- 我想让它与 self、&self、mut self 和 &mut self 方法一起正常工作。如何适当地实施 DerefMut?
What is wrong with my implementation and how do make it work?
String::into_bytes
移动 String
,在你的情况下你只能访问它的引用 &
,所以你不能移动它。
您可以使用 bytes
其中 returns 一个字节的迭代器而不移动它:
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let b = w.bytes();
println!("{b:?}");
}
I'd like to make it work properly with self, &self, mut self, &mut self methods. How do I also implement DerefMut appropriately?
您需要考虑签名,一般来说:
Deref
-> 得到一个&T
DerefMut
-> 得到一个&mut
From/Into
-> 将类型转换为其他类型的拥有版本T
示例使用 From/Into
:
struct Wrapper(String);
impl From<Wrapper> for String {
fn from(w: Wrapper) -> String {
w.0
}
}
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let s: String = w.into();
let bytes = s.into_bytes();
println!("{bytes:?}");
}
您还可以考虑查看 std::borrow
模块,它具有允许您像其他类型一样使用您的类型的特性。
最后,您的方法可能会奏效,但如前所述,在这种情况下您不能从 &T
转到 U
(您可以 T
转到 U
) .剩下的解决方案是 Clone
并创建一个拥有的副本:
use std::ops::Deref;
struct Wrapper(String);
impl Deref for Wrapper {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0 //pointer to Inner value
}
}
fn main() {
let d = "Dog".to_string();
let w = Wrapper(d);
let b = w.deref().clone().into_bytes();
println!("{b:?}");
}