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

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

Issue with matching enum with options

问题

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

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

我遇到的问题是无法通过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

   pub struct Addr&lt;&#39;x&gt; {
    pub name: Option&lt;Cow&lt;&#39;x, str&gt;&gt;,
    pub address: Option&lt;Cow&lt;&#39;x, str&gt;&gt;,
}

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

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

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"),
}
}


打印
&gt; Parsed name=Some(&quot;somename&quot;) address=None

或者对匹配不同组合有更多控制的话:

```rust
match value {
        HeaderValue::Address(Addr{name:Some(name), address:Some(address)}) =&gt; println!(&quot;Parsed both name={:?} address={:?}&quot;, name, address),
        HeaderValue::Address(Addr{address:Some(address), ..}) =&gt; println!(&quot;Parsed only address={:?}&quot;, address),
        HeaderValue::Address(Addr{name:Some(name), ..}) =&gt; println!(&quot;Parsed only name={:?}&quot;, name),
        HeaderValue::Address(Addr{..}) =&gt; println!(&quot;Parsed empty&quot;),
        _ =&gt; println!(&quot;Couldn&#39;t match&quot;),
}

打印
> Parsed only name="somename"

对评论的回答:

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

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

打印:
> Parsed name="somename"


<details>
<summary>英文:</summary>

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"),
}
}


Prints
&gt; Parsed name=Some(&quot;somename&quot;) address=None

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"),
}

Prints
&gt; Parsed only name=&quot;somename&quot;

## Answer to the comment:
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);
}

Prints:
&gt; Parsed name=&quot;somename&quot;

</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:

确定