簡體   English   中英

有什么方法可以實現 Into&lt;&amp;str&gt; 或 From<T> 對於 &amp;str?

[英]Is there any way to implement Into<&str> or From<T> for &str?

正在用 Rust 編寫一些代碼,試圖定義一個 CLI,使用(否則非常棒) crate clap ,並遇到了一個相當關鍵的問題。 App方法接受Into<&'help str> ,我一直無法找到實現此特征的方法。

事實上,據我所知,這是絕對無法實現的:

struct JustWorkDamnIt {
    string: String
}

impl From<JustWorkDamnIt> for &str {
    fn from(arg: JustWorkDamnIt) -> Self {
        return arg.string.as_str()
    }
}

...產生:

error[E0515]: cannot return value referencing local data `arg.string`
  --> src/cmd/interactive.rs:25:16
   |
25 |         return arg.string.as_str()
   |                ----------^^^^^^^^^
   |                |
   |                returns a value referencing data owned by the current function
   |                `arg.string` is borrowed here

然而,有趣的是,返回一個文字編譯就好了(我認為這就是為什么clap不介意使用這個特性)。 大概是因為文字被編譯到某個靜態內存區域,因此不屬於該函數:

impl From<JustWorkDamnIt> for &str {
    fn from(arg: JustWorkDamnIt) -> Self {
        return "literal"
    }
}

但是,我的意思是,肯定有一種方法可以實現此特征並返回動態字符串嗎? 也許巧妙地使用 Box<> 之類的,idk。 我相信我已經嘗試了所有我能想到的事情。

如果沒有辦法,那么這對於 Rust 來說似乎是一個非常明顯的缺陷 - 可以在函數頭中聲明和使用的特性,但實際上不能有意義地實現(返回文字沒有多大意義)。 如果結果確實如此,我將在 rust-lang 存儲庫上為此流程創建一個問題,但首先我想在這里檢查我的發現。


UPD:感謝您的評論,讓我更深入地思考這個問題。

問題似乎與生命有關。 我很抱歉沒有展示整個代碼,我認為我分享的片段會充分描述問題,但事后看來,上下文對 Rust 的生命周期很重要確實是有道理的。

我確實為這個特定的問題實例找到了“解決方案”。 由於有問題的代碼在每個可執行文件啟動時只會運行一次,我可以只使用Box::leak &'static str並將其稱為一天。 不過,我想弄清楚是否有更通用的解決方案可用於經常創建的動態字符串。

impl Cmd for InteractiveCmd {
    fn build_args_parser<'a, 'b>(&'b self, builder: App<'a>) -> App<'a> {
        // leak() works here but i'm curious if there's a better way
        let staticStr : &'static str = Box::leak(Box::from(format!("Interactive {} shell", APPNAME).as_str()));
        let rv = builder
            // pub fn about<S: Into<&'b str>>(mut self, about: S) -> Self
            .about(staticStr) 
            .version("0.1");
        return rv;
    }
}

fn main() {
    let interactive = InteractiveCmd::new();
    let mut app = App::new(APPNAME)
        .version(APPVER)
        .author(AUTHORS)
      .subcommand(interactive.build_args_parser(App::new("interactive")));
}

目前我在這里面臨兩個困惑點:

  • 為什么impl From<String> for &str沒有impl From<String> for &str 編譯器聲稱impl From<String> for &mut str存在一個,我在這里沒有看到mut的重要性。
  • ...如果有充分的理由不impl From<String> for &str ,那么以某種方式阻止在庫的公共 API 中使用Into<&str>是否有意義?

或者也許問題出在我的 build_args_parser 函數上,就 Rust 而言,它不是將工作卸載給它的選項?

似乎您正在嘗試將String轉換為&'a str 你可以這樣做:

use clap::App;

fn main() {
    let s = format!("Interactive {} shell", "Testing");
    let app = App::new("Testing")
        .about(&*s); // or `.about(s.as_str());` it's the same
}

這是我們要調用的函數的簽名:

pub fn about<S: Into<&'b str>>(self, about: S) -> Self

所以about參數必須實現 trait Into<&'b str> 根據std::convert::Into ,我們知道&'b str確實實現了特征Into<&'b str> 所以現在我們只需要一種方法將String轉換為&'b str std::string::String告訴我們有兩種方法:使用s.as_str()&*s

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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