我正在编写一个非常简单的getter/setting模型,我想在Rust中使用struct
和出于简单的原因使用和impl
.
struct Person {
firstName: String,
lastName: String,
}
impl Person {
fn get_first_name(&mut self) -> String { return self.firstName; }
fn get_last_name(&mut self) -> String { return self.lastName; }
fn set_first_name(&mut self, x: String) { self.firstName = x; }
fn set_last_name(&mut self, x: String) { self.lastName = x; }
fn default() -> Person {
Person {firstName: "".to_string(), lastName: "".to_string()}
}
}
fn main() {
let mut my_person : Person = Person{ ..Person::default() };
my_person.set_first_name("John".to_string());
my_person.set_last_name("Doe".to_string());
println!("{}", my_person.firstName);
println!("{}", my_person.lastName);
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码段时,我收到以下错误.
src\main.rs:7:53: 7:57 error: cannot move out of borrowed content [E0507]
src\main.rs:7 fn get_first_name(&mut self) -> String { return self.firstName; }
^~~~
src\main.rs:8:53: 8:57 error: cannot move out of borrowed content [E0507]
src\main.rs:8 fn get_last_name(&mut self) -> String { return self.lastName; }
^~~~
error: aborting due to 2 previous errors
Could not compile `sandbox`.
Run Code Online (Sandbox Code Playgroud)
有人可以向我指出这个错误,因为我对Rust很新吗?
有关更好地编写此代码段的提示也将被接受.我一直在寻找更容易/更快的可读性.
DK.*_*DK. 23
好的,这里的具体问题是无法摆脱借来的内容.这已经回答了 无数 次 之前在各种条件下,更不用提在锈图书所有权主体的章节.
更有趣的是吸气剂和二传手.是的,你可以用Rust写它们,但它们可能不是最好的选择.
在我继续之前,我只想注意,绝对没有理由要求&mut self
使用getter ...除非你打算修改值作为删除值的一部分,但是那时你并没有真正处理任何getter更多.
其次,你不应该 clone
在吸气器中.如果所有用户想要做的是例如从值中读取,那么这是非常浪费的.最好返回一个不可变的借位,clone
如果需要,用户可以从中借用.
无论如何,如果你正在写这些因为你想要某种逻辑运行以验证新值,那就继续使用setter.否则,你可以这样做:
#[derive(Default)]
struct Person {
first_name: String,
last_name: String,
}
impl Person {
// Immutable access.
fn first_name(&self) -> &String {
&self.first_name
}
fn last_name(&self) -> &String {
&self.last_name
}
// Mutable access.
fn first_name_mut(&mut self) -> &mut String {
&mut self.first_name
}
fn last_name_mut(&mut self) -> &mut String {
&mut self.last_name
}
}
fn main() {
let mut my_person = Person::default();
*my_person.first_name_mut() = String::from("John");
*my_person.last_name_mut() = "Doe".into();
println!("first_name: {}", my_person.first_name());
println!("last_name: {}", my_person.last_name());
// Can't do this efficiently with getter/setter!
{
let s = my_person.last_name_mut();
s.truncate(2);
s.push('w');
}
println!("first_name: {}", my_person.first_name());
println!("last_name: {}", my_person.last_name());
}
Run Code Online (Sandbox Code Playgroud)
这为用户提供了或多或少的直接访问权限,而无需实际让他们直接访问这些字段.除了编写新值之外,这还允许用户就地改变现有值,这对于大量堆分配的东西很重要.
另外,我做了一些其他改动:
你可以机械地推导出来Default
; 在这种情况下没有理由自己写.
传统风格适用snake_case
于田野.
你创建它的方式Person
是不必要的回旋.
你的 getter 方法借用了self
. 当您返回时self.name
,您正在name
从不允许的借用参考资料中移出。您应该返回 name 的副本。
此外,您不需要self
在 getter 方法中传递可变引用,因为您没有修改内部结构。
因此,您的 getter 方法应该是:
fn get_first_name(&self) -> &String { &self.firstName }
fn get_last_name(&self) -> &String { &self.lastName }
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10322 次 |
最近记录: |