什么';在Rust枚举中str/String值的最佳实践是什么?

什么';在Rust枚举中str/String值的最佳实践是什么?,string,enums,rust,lifetime,String,Enums,Rust,Lifetime,我有一个非常悦目的想法,但我担心它的含义: #[derive(Eq, PartialEq, Debug)] pub enum SmtpHost { DOMAIN(String), IPV4(Ipv4Addr), IPV6(Ipv6Addr), UNKNOWN { label:String, literal:String }, } 我用一个PEG语法来填充它,它给了我&str,所以所有的string调用都是这样的-SmtpHost::Domain(s.t

我有一个非常悦目的想法,但我担心它的含义:

#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost {     
    DOMAIN(String),
    IPV4(Ipv4Addr),
    IPV6(Ipv6Addr),
    UNKNOWN { label:String, literal:String },
}
我用一个PEG语法来填充它,它给了我
&str
,所以所有的string调用都是这样的-
SmtpHost::Domain(s.to_string())

我希望这些枚举是解析器的结果,比如
smtp\u parser::host<'input>(s:'input&str)->SmtpHost

我也尝试过ref方法,但很快就会变得笨拙:

#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost<'a > {     
    DOMAIN(&'a str),
    IPV4(Ipv4Addr),
    IPV6(Ipv6Addr),
    UNKNOWN { label:&'a str, literal:&'a str },
}
#[派生(Eq、PartialEq、Debug)]

pub enum SmtpHost如果要在不复制的情况下进行分析, 那么你想要的签名是:

// Notice that the 'input goes after the &. Syntax.
fn smtp_parser::host<'input>(s: &'input str) -> SmtpHost<'input>;

如果主机部件有时可以直接从输入中使用,但有时需要在可用之前进行更改,则需要执行此操作。

如果要在不复制的情况下进行解析, 那么你想要的签名是:

// Notice that the 'input goes after the &. Syntax.
fn smtp_parser::host<'input>(s: &'input str) -> SmtpHost<'input>;

如果主机部件有时可以直接从输入中使用,但有时需要在可用之前进行更改,则需要执行此操作。

str
String
之间的关键区别在于所有权<代码>字符串为所有,但
&str
为借用。如果存储
&str
值,则容器的生存期将限制为借用字符串的生存期

如果您的解析器生成器生成具有以下签名的解析函数:

#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost<'input> {
    DOMAIN(&'input str),
    IPV4(Ipv4Addr),
    IPV6(Ipv6Addr),
    UNKNOWN { label: &'input str, literal: &'input str },
}
smtp_parser::host<'a>(&'a str) -> SmtpHost<'a>
你会得到一个错误,比如说“线的寿命不够长”

因此,当您只是从其他地方借用一个不需要比源代码寿命长的值时,应该使用
&str
。当您需要拥有该值的所有权时,应该使用
String


对于更复杂的情况,
&str
String
之间的关键区别在于所有权,在这种情况下,您需要拥有一个自己的值,但希望能够在多个位置使用它,而不需要很多副本<代码>字符串为所有,但
&str
为借用。如果存储
&str
值,则容器的生存期将限制为借用字符串的生存期

如果您的解析器生成器生成具有以下签名的解析函数:

#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost<'input> {
    DOMAIN(&'input str),
    IPV4(Ipv4Addr),
    IPV6(Ipv6Addr),
    UNKNOWN { label: &'input str, literal: &'input str },
}
smtp_parser::host<'a>(&'a str) -> SmtpHost<'a>
你会得到一个错误,比如说“线的寿命不够长”

因此,当您只是从其他地方借用一个不需要比源代码寿命长的值时,应该使用
&str
。当您需要拥有该值的所有权时,应该使用
String


对于更复杂的情况,您需要拥有一个自己的值,但希望能够在多个位置使用它,而不需要它的多个副本,因此有
Rc
RcSide注意:rust中的枚举变量通常是用
CamelCase
编写的,而不是
FULLCAPS
。你可能有特定的理由这样做,在这种情况下,我道歉。但是如果没有,只需遵守约定:)
&str
不是所有的,因此如果您想在解析器完成后保留您的令牌,您可能必须使用
String
谢谢@Kroltan,willdo@zstewart,我是否认为这是一个答案?我希望这些枚举是解析器的结果,比如
smtp_parser::host<'input>(s:'input&str)->SmtpHost
@RobertCutajar Robajz如果使用
&str
和该生存期参数返回
&str
,则返回的
SmtpHost
必须有一个生存期(s:&'input str)->SmtpHostSide注意:rust中的Enum变体通常使用
CamelCase
编写,而不是
FULLCAPS
。你可能有特定的理由这样做,在这种情况下,我道歉。但是如果没有,只需遵守约定:)
&str
不是所有的,因此如果您想在解析器完成后保留您的令牌,您可能必须使用
String
谢谢@Kroltan,willdo@zstewart,我是否认为这是一个答案?我希望这些枚举是解析器的结果,比如
smtp_parser::host<'input>(s:'input&str)->SmtpHost
@RobertCutajar Robajz如果使用
&str
和该生存期参数返回
&str
,则返回的
SmtpHost
必须有一个生存期(s:&'input str)->smtphostThank for the Cow@notridleThank for the Cow@notridleThank@zstewart,旁注,rust Playder链接无法通过我的浏览器,请尝试缩小它,但我明白了重点。@RobertCutajar Robajz hm。奇怪的是,它似乎对我有用。我最初尝试使用Rust Playerd的链接缩短器,但StackOverflow显然不喜欢链接缩短器。不幸的是,完整的URL包含了示例的完整代码。。。也许它比你的浏览器满意的长。谢谢@zstewart,旁注,rust Playerd链接不会通过我的浏览器,试着缩小它,但我明白了重点。@RobertCutajar Robajz hm。奇怪的是,它似乎对我有用。我最初尝试使用Rust Playerd的链接缩短器,但StackOverflow显然不喜欢链接缩短器。不幸的是,完整的URL包含了示例的完整代码。。。也许它比你的浏览器满意的要长。