[英]What's the best practice for str/String values in Rust enums?
我覺得這真令人愉悅,但是我擔心它的含義:
#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost {
DOMAIN(String),
IPV4(Ipv4Addr),
IPV6(Ipv6Addr),
UNKNOWN { label:String, literal:String },
}
我從PEG語法填充了該語法,這給了我&str
所以所有的&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)
我的學習項目供參考
如果要分析而不復制,則所需的簽名是:
// Notice that the 'input goes after the &. Syntax.
fn smtp_parser::host<'input>(s: &'input str) -> SmtpHost<'input>;
然后可以這樣定義枚舉:
#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost<'input> {
DOMAIN(&'input str),
IPV4(Ipv4Addr),
IPV6(Ipv6Addr),
UNKNOWN { label: &'input str, literal: &'input str },
}
另一方面,如果在某些情況下這太尷尬,則可以使用Cow
(寫時復制)類型來完成這兩種操作:
use std::borrow::Cow;
#[derive(Eq, PartialEq, Debug)]
pub enum SmtpHost<'input> {
DOMAIN(Cow<'input, str>),
IPV4(Ipv4Addr),
IPV6(Ipv6Addr),
UNKNOWN { label: Cow<'input, str>, literal: Cow<'input, str> },
}
如果主機部件有時可以直接在輸入中使用,但是有時需要更改才能使用,這就是您要執行的操作。
&str
和String
之間的關鍵區別是所有權。 擁有String
,但借用&str
。 如果存儲&str
值,則容器的生存期將限制為借用字符串的生存期。
如果您的解析器生成器生成具有以下簽名的解析函數:
smtp_parser::host<'a>(&'a str) -> SmtpHost<'a>
然后,當它傳遞給您一個&str
供您用來構造解析樹/解析值時,很可能會給您輸入的子字符串。 這意味着您存儲在SmtpHost
枚舉中的&str
的生存期必須短於原始輸入字符串。 確實,您可以在簽名中看到這一點; 輸入字符串和輸出SmtpHost
都具有生存期參數'a
。
這意味着您生成的SmtpHost
不能超過用於生成它的輸入。 如果輸入是字符串常量&'static str
,可能沒問題,但是如果您是從標准輸入中獲取文件或正在讀取文件,則無法通過輸入字符串所在的點來返回SmtpHost
擁有的。
例如,假設您要聲明一個函數,該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)
}
您會收到一條錯誤消息,提示“線路壽命不足”。 這是Rust操場上的一個小例子 。
因此,當您只是從其他地方借入值而無需使用源代碼時,應使用&str
。 需要擁有值的所有權時,應使用String
。
對於更復雜的情況,您需要擁有一個擁有的值,但又希望能夠在多個地方使用它而又沒有太多的副本,因此有Rc<T>
和Rc<RefCell<T>
。 但在您的情況下,聽起來SmtpHost
應該只擁有對其存儲的字符串的所有權。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.