什么';在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包含了示例的完整代码。。。也许它比你的浏览器满意的要长。