Rust 具有默认实现和所需结构成员的Trait
我有一个锈病特征,应该给vector增加一个值。为了使Rust 具有默认实现和所需结构成员的Trait,rust,traits,Rust,Traits,我有一个锈病特征,应该给vector增加一个值。为了使add_job函数工作,必须确保在为具体结构实现特征时存在向量 下面的代码当然会失败,因为作业从未实现过。这只是为了证明我的意图: trait人物{ //添加作业的默认实现 fn添加作业(&self,作业:字符串){ self.jobs.push(作业) } } 结构客户{ //添加作业用作默认实现 //由特质提供 } 为客户提供咨询服务{ //一些东西 } fn main(){ 让mut-george=Customer{}; 在字符串()中
add_job
函数工作,必须确保在为具体结构实现特征时存在向量
下面的代码当然会失败,因为作业从未实现过。这只是为了证明我的意图:
trait人物{
//添加作业的默认实现
fn添加作业(&self,作业:字符串){
self.jobs.push(作业)
}
}
结构客户{
//添加作业用作默认实现
//由特质提供
}
为客户提供咨询服务{
//一些东西
}
fn main(){
让mut-george=Customer{};
在字符串()中添加作业(“程序员”);
}
有没有一种方法可以使trait同时提供struct成员
可能不会,但解决上述问题的“生锈”方法是什么?Traits不能提供或要求结构字段。虽然在traits中有一个关于允许字段的定义。然而,目前还没有任何不稳定的特性允许这样做
不过,你仍然可以简化你正在尝试做的事情。我冒昧地重新命名并更改了您的特征,以便能够提供更全面的示例
让我们考虑一下<代码>作业特性。它定义了各种方法,所有这些方法都需要
jobs:Vec
字段
trait作业{
fn添加作业(&mut self,作业:字符串);
fn清除作业(&mut self);
fn count_jobs(&self)->usize;
}
使用宏 一种解决方案是使用一个实现所有这些方法的
宏
macro\u规则!使用\u字段执行\u作业\u{
($($t:ty),+$(,)?)=>($(
以$t的价格提供就业机会{
fn添加作业(&mut self,作业:字符串){
self.jobs.push(作业);
}
fn清除作业(&mut self){
self.jobs.clear();
}
fn计数作业(&self)->使用{
self.jobs.len()
}
}
)+)
}
然后,通过使用宏,您可以轻松地重用代码
struct-Person{
乔布斯:Vec,
}
结构客户{
乔布斯:Vec,
}
用字段执行作业!(人);
用字段执行作业!(客户);
//或
用字段执行作业!(个人、客户);
使用第二个HasJobs
trait
另一个解决方案是引入第二个HasJobs
trait。如果类型实现了HasJobs
,则可以使用forJobs
trait有工作{
fn作业(&self)->&[String];
fn jobs_mut(&mut self)->&mut Vec;
}
为T{
fn添加作业(&mut self,作业:字符串){
self.jobs_mut().push(作业);
}
fn清除作业(&mut self){
self.jobs_mut().clear();
}
fn计数作业(&self)->使用{
self.jobs().len()
}
}
现在仍然需要为所有类型实现HasJobs
。但是如果作业
有大量的方法。那么实现HasJobs
就容易多了。我们也可以使用宏执行此操作:
macro\u规则!impl_有工作{
($($t:ty),+$(,)?)=>($(
impl公司的工作费用为$t{
fn作业(&self)->&[String]{
&自谋职业
}
fn jobs_mut(&mut self)->&mut Vec{
&多个自助作业
}
}
)+)
}
再一次,你只要做:
struct-Person{
乔布斯:Vec,
}
结构客户{
乔布斯:Vec,
}
impl_有工作!(人);
impl_有工作!(客户);
//或
impl_有工作!(个人、客户);
使用
Deref
和DerefMut
最后,如果Customer
始终是Person
,则可以将Person
更改为struct
并使用组合,即将Person:Person
添加到Customer
(和其他类型)
因此,首先,impl个人工作
:
struct-Person{
乔布斯:Vec,
}
为个人提供就业机会{
fn添加作业(&mut self,作业:字符串){
self.jobs.push(作业);
}
fn清除作业(&mut self){
self.jobs.clear();
}
fn计数作业(&self)->使用{
self.jobs.len()
}
}
然后,现在您可以使用and将客户
解除对人员
的引用。因此,所有Person
的方法都可以直接通过Customer
获得
但是,只有当您只有一个“特征”时,此解决方案才有效,即您只能Deref
Customer
到Person
。您将无法将Deref
Customer
转移到SomethingElse
使用std::ops:{Deref,DerefMut};
结构客户{
人:人,,
}
为客户执行订单{
类型目标=人;
fn deref(&self)->&self::Target{
&自我人
}
}
为客户提供的impl DerefMut{
fn deref_mut(&mut self)->&mut self::Target{
&多个人
}
}
作为评论,traitsI已经在寻找一些RFC允许字段。不过还是要谢谢你的提醒!:)回答得很好,比我期望的要多!不客气。很高兴我能帮忙:)