gpt4 book ai didi

string - Rust 枚举中 str/String 值的最佳实践是什么?

转载 作者:行者123 更新时间:2023-11-29 08:23:46 25 4
gpt4 key购买 nike

我有这个非常赏心悦目,但我担心它的含义:

#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost {
DOMAIN(String),
IPV4(Ipv4Addr),
IPV6(Ipv6Addr),
UNKNOWN { label:String, literal:String },
}

我正在用一个 PEG 语法来填充它,它给了我 &str所以所有的字符串调用看起来像这样 - SmtpHost::Domain(s.to_string())

我希望这些枚举是解析器的结果,比如 smtp_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 },
}

所以我喜欢要么/要么......但你知道得更多。告诉我:o)

我的 study project for reference

最佳答案

&str 之间的关键区别和 String是所有权。 String拥有,但是 &str是借来的。如果您存储 &str值,容器的生命周期将被限制为借用字符串的生命周期。

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

smtp_parser::host<'a>(&'a str) -> SmtpHost<'a>

然后当它传递给你一个 &str为了让您用来构建解析树/解析值,它很可能会为您提供输入的子字符串。这意味着 &str你存储在你的SmtpHost枚举的生命周期必须短于原始输入字符串。事实上,您可以在签名中看到这一点;输入字符串和输出 SmtpHost有生命周期参数 'a .

这意味着您的结果 SmtpHost不能超过用于生成它的输入。如果输入是字符串常量,&'static str ,这可能没问题,但如果您从标准文件中获取输入或读取文件,您将无法返回 SmtpHost超过输入字符串所属的点。

例如,假设您要声明一个解析 SmtpHost 的函数从标准中:

fn read_host<'a>() -> SmtpHost<'a> {
let mut line = String::new();
let stdin = io::stdin();
stdin.lock().read_line(&mut line).expect("Could not read line");
smtp_parser::host(&line)
}

您会收到一条错误消息,例如“行的生命周期不够长”。 Here's a trivial example in Rust playground .

所以你应该使用&str当您只是从其他地方借用不需要比来源更长寿的值(value)时。你应该使用 String当您需要拥有值(value)的所有权时。

对于更复杂的情况,您需要拥有一个拥有的值,但希望能够在多个地方使用它而不需要它的多个副本,为此有 Rc<T>Rc<RefCell<T> .但在你的情况下,这听起来像 SmtpHost应该只拥有它存储的字符串的所有权。

关于string - Rust 枚举中 str/String 值的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44054746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com