簡體   English   中英

Rust枚舉中str / String值的最佳實踐是什么?

[英]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> },
}

如果主機部件有時可以直接在輸入中使用,但是有時需要更改才能使用,這就是您要執行的操作。

&strString之間的關鍵區別是所有權。 擁有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM