Rust 具有默认实现和所需结构成员的Trait

Rust 具有默认实现和所需结构成员的Trait,rust,traits,Rust,Traits,我有一个锈病特征,应该给vector增加一个值。为了使add_job函数工作,必须确保在为具体结构实现特征时存在向量 下面的代码当然会失败,因为作业从未实现过。这只是为了证明我的意图: trait人物{ //添加作业的默认实现 fn添加作业(&self,作业:字符串){ self.jobs.push(作业) } } 结构客户{ //添加作业用作默认实现 //由特质提供 } 为客户提供咨询服务{ //一些东西 } fn main(){ 让mut-george=Customer{}; 在字符串()中

我有一个锈病特征,应该给vector增加一个值。为了使
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
,则可以使用for
Jobs

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允许字段。不过还是要谢谢你的提醒!:)回答得很好,比我期望的要多!不客气。很高兴我能帮忙:)