我有一个Message结构,它有一个字段,我想在调用方法时修改它。
这个Message结构有一个attachments字段,它是一个Option<Vec<Attachment>>.
我的目标是能够调用一个方法Message来将一个Attachment对象推送到attachments Vec.
#[derive(Debug, Serialize, Deserialize)]
pub struct Message {
/// The verified sender email address
#[serde(rename = "FromEmail")]
pub from_email: String,
/// The name of the sender
#[serde(rename = "FromName")]
pub from_name: String,
/// The subject of the email
#[serde(rename = "Subject")]
pub subject: Option<String>,
/// The raw text content of the email
#[serde(rename = "Text-part")]
pub text_part: String,
/// The HTML content of the email
#[serde(rename = "Html-part")]
pub html_part: Option<String>,
#[serde(rename = "Recipients")]
pub recipients: Vec<Recipient>,
#[serde(rename = "Attachments")]
pub attachments: Option<Vec<Attachment>>,
#[serde(rename = "Inline_attachments")]
pub inline_attachments: Option<Vec<InlineAttachments>>,
}
Run Code Online (Sandbox Code Playgroud)
以下是我当前对将Attachment对象推送到 的方法的实现Option<Vec<Attachment>>:
pub fn attach(&mut self, attachment: Attachment) {
// if theres no attachments already
// initialize the attachments vector
if self.attachments.is_none() {
let mut attachments = Vec::new();
attachments.push(attachment);
self.attachments = Some(attachments);
} else {
// Where this is invalid as theres no `clone` for `Option<Vec<Attachment>>`
let attachments = self.attachments.clone();
attachments.push(attachment);
}
}
Run Code Online (Sandbox Code Playgroud)
这是实现Attachment struct:
use serde::{Deserialize, Serialize};
/// An email attachment
#[derive(Debug, Serialize, Deserialize)]
pub struct Attachment {
#[serde(rename = "Content-type")]
pub content_type: String,
#[serde(rename = "Filename")]
pub filename: String,
pub content: String,
}
Run Code Online (Sandbox Code Playgroud)
问题出在else块上,其中attachents Option字段被解包,然后一个attachment对象被推送到Vec.
问题是Attachment无法实现Copy特征。
对于 Rust 中的此类场景,哪种方法是正确的?
提前致谢!
Option有各种各样的辅助方法可以在这里提供帮助。如果Vec有的话,你基本上想改变已经存在的那个,如果没有,创建一个并改变它。你可以用 来做到这一点Option::get_or_insert_with,它返回一个&mut Vec<Attachment>。这样,您就可以将项目推到最后。一个最小的可编译示例如下所示:
pub struct Message {
pub attachments: Option<Vec<Attachment>>,
}
#[derive(Debug)]
pub struct Attachment {
pub content_type: String,
pub filename: String,
pub content: String,
}
impl Message {
pub fn attach(&mut self, attachment: Attachment) {
self.attachments
.get_or_insert_with(Vec::new)
.push(attachment);
}
}
fn main() {
let mut m = Message { attachments: None };
let a = Attachment {
content_type: "application/json".into(),
filename: "foo.json".into(),
content: "{}".into(),
};
m.attach(a);
assert_eq!(m.attachments.unwrap()[0].content, "{}");
}
Run Code Online (Sandbox Code Playgroud)
如果您在 if-else 情况下使用is_someor is_none(or, for Result, is_okor is_err),这通常表明您可能想要重新考虑您在做什么,因为这在 Rust 中通常不是很惯用的。通常,有一种辅助方法可以以更简单、更易于使用的方式完成您想要的操作。
| 归档时间: |
|
| 查看次数: |
179 次 |
| 最近记录: |