问题与匹配枚举选项相关。

huangapple go评论88阅读模式
英文:

Issue with matching enum with options

问题

我需要解析邮件的解析器,并且我需要从中提取发件人的详细信息。我使用了Rust的mail_parser库,其中通过from方法提取了解析后的发件人信息。from方法返回了一个名为HeaderValue的枚举类型。但我不明白的是,如果我需要获取Address(Addr<'x>)Address是一个包含以下选项的结构体:

  1. pub struct Addr<'x> {
  2. pub name: Option<Cow<'x, str>>,
  3. pub address: Option<Cow<'x, str>>,
  4. }

我遇到的问题是无法通过match语句从Address(Addr<'x>)中提取数据并获取选项中的nameaddress字段。我应该如何编写match语句来实现这个目的?

英文:

I have this parser which used to parse mail and i need to parse the from details from i use rust mail_parser crate. there the parsed input from details are extracted using from method the from method returns an enum called HeaderValue link

what i can't understand is if i need to get the Address(Addr&lt;&#39;x&gt;) the Address is an option which contains this option

  1. pub struct Addr&lt;&#39;x&gt; {
  2. pub name: Option&lt;Cow&lt;&#39;x, str&gt;&gt;,
  3. pub address: Option&lt;Cow&lt;&#39;x, str&gt;&gt;,
  4. }

what i'm getting issue is can't make the match to get the data from the Address(Addr&lt;&#39;x&gt;) and extract the option. if i need to get the name and address fields to struct how can i make the match statement?.

答案1

得分: 0

  1. 它不难,只是标准语法。你具体遇到了什么错误?

use std::borrow::Cow;

pub struct Addr<'x> {
pub name: Option<Cow<'x, str>>,
pub address: Option<Cow<'x, str>>,
}

pub enum HeaderValue<'x> {
Address(Addr<'x>),
AddressList(Vec<Addr<'x>>),
Empty,
}

fn main() {
let value = HeaderValue::Address(Addr{name: Some("somename".into()), address: None});
match value {
HeaderValue::Address(Addr{name, address}) => println!("Parsed name={:?} address={:?}", name, address),
_ => println!("Couldn't match"),
}
}

  1. 打印
  2. &gt; Parsed name=Some(&quot;somename&quot;) address=None
  3. 或者对匹配不同组合有更多控制的话:
  4. ```rust
  5. match value {
  6. HeaderValue::Address(Addr{name:Some(name), address:Some(address)}) =&gt; println!(&quot;Parsed both name={:?} address={:?}&quot;, name, address),
  7. HeaderValue::Address(Addr{address:Some(address), ..}) =&gt; println!(&quot;Parsed only address={:?}&quot;, address),
  8. HeaderValue::Address(Addr{name:Some(name), ..}) =&gt; println!(&quot;Parsed only name={:?}&quot;, name),
  9. HeaderValue::Address(Addr{..}) =&gt; println!(&quot;Parsed empty&quot;),
  10. _ =&gt; println!(&quot;Couldn&#39;t match&quot;),
  11. }

打印
> Parsed only name="somename"

对评论的回答:

我认为你不能在单个 match 语句中实现这个,但你可以使用多个 if let 语句,像这样:

  1. let value = HeaderValue::Address(Addr{name: Some(&quot;somename&quot;.into()), address: None});
  2. if let HeaderValue::Address(Addr{address:Some(address), ..}) = &amp;value {
  3. println!(&quot;Parsed address={:?}&quot;, address);
  4. }
  5. if let HeaderValue::Address(Addr{name:Some(name), ..}) = &amp;value {
  6. println!(&quot;Parsed name={:?}&quot;, name);
  7. }

打印:
> Parsed name="somename"

  1. <details>
  2. <summary>英文:</summary>
  3. It&#39;s not any hard, just the standard syntax. What errors did you face exactly?

use std::borrow::Cow;

pub struct Addr<'x> {
pub name: Option<Cow<'x, str>>,
pub address: Option<Cow<'x, str>>,
}

pub enum HeaderValue<'x> {
Address(Addr<'x>),
AddressList(Vec<Addr<'x>>),
Empty,
}

fn main() {
let value = HeaderValue::Address(Addr{name: Some("somename".into()), address: None});
match value {
HeaderValue::Address(Addr{name, address}) => println!("Parsed name={:?} address={:?}", name, address),
_ => println!("Couldn't match"),
}
}

  1. Prints
  2. &gt; Parsed name=Some(&quot;somename&quot;) address=None
  3. Or for more control over matching different combinations:

match value {
HeaderValue::Address(Addr{name:Some(name), address:Some(address)}) => println!("Parsed both name={:?} address={:?}", name, address),
HeaderValue::Address(Addr{address:Some(address), ..}) => println!("Parsed only address={:?}", address),
HeaderValue::Address(Addr{name:Some(name), ..}) => println!("Parsed only name={:?}", name),
HeaderValue::Address(Addr{..}) => println!("Parsed empty"),
_ => println!("Couldn't match"),
}

  1. Prints
  2. &gt; Parsed only name=&quot;somename&quot;
  3. ## Answer to the comment:
  4. I don&#39;t think you can do that with a single `match` statement, but you can do multiple `if let` statements like so

let value = HeaderValue::Address(Addr{name: Some("somename".into()), address: None});
if let HeaderValue::Address(Addr{address:Some(address), ..}) = &value {
println!("Parsed address={:?}", address);
}
if let HeaderValue::Address(Addr{name:Some(name), ..}) = &value {
println!("Parsed name={:?}", name);
}

  1. Prints:
  2. &gt; Parsed name=&quot;somename&quot;
  3. </details>

huangapple
  • 本文由 发表于 2023年5月11日 16:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225604.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定