[英]Is there any way to implement Into<&str> or From<T> for &str?
Was writing some code in Rust trying to define a CLI, using the (otherwise pretty great) crate clap
, and run into a rather critical issue.正在用 Rust 编写一些代码,试图定义一个 CLI,使用(否则非常棒) crate
clap
,并遇到了一个相当关键的问题。 Methods of App
accept an Into<&'help str>
, and i've been unable to find a way to implement this trait. App
方法接受Into<&'help str>
,我一直无法找到实现此特征的方法。
Indeed from what i understand, it is absolutely unimplementable:事实上,据我所知,这是绝对无法实现的:
struct JustWorkDamnIt {
string: String
}
impl From<JustWorkDamnIt> for &str {
fn from(arg: JustWorkDamnIt) -> Self {
return arg.string.as_str()
}
}
...which yields: ...产生:
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
Interestingly enough, however, returning a literal compiles just fine (which i reckon is why clap
doesn't mind using this trait).然而,有趣的是,返回一个文字编译就好了(我认为这就是为什么
clap
不介意使用这个特性)。 Presumably that's because the literal is compiled to some static region of memory and therefore isn't owned by the function:大概是因为文字被编译到某个静态内存区域,因此不属于该函数:
impl From<JustWorkDamnIt> for &str {
fn from(arg: JustWorkDamnIt) -> Self {
return "literal"
}
}
But, i mean, surely there's a way to implement this trait and return dynamic strings?但是,我的意思是,肯定有一种方法可以实现此特征并返回动态字符串吗? Maybe some clever use of Box<> or something, idk.
也许巧妙地使用 Box<> 之类的,idk。 I believe i've tried all the things i could think of.
我相信我已经尝试了所有我能想到的事情。
And if there isn't a way, then this seems like a pretty glaring flaw for Rust - traits which can be declared and used in function headers, but cannot be actually implemented meaningfully (there's not much of a point in returning a literal).如果没有办法,那么这对于 Rust 来说似乎是一个非常明显的缺陷 - 可以在函数头中声明和使用的特性,但实际上不能有意义地实现(返回文字没有多大意义)。 If this turns out to be the case i'll create an issue on the rust-lang repository for this flow, but first i wanted to sanity-check my findings here.
如果结果确实如此,我将在 rust-lang 存储库上为此流程创建一个问题,但首先我想在这里检查我的发现。
UPD: Thanks for the comments, made me think more in-depth about this issue. UPD:感谢您的评论,让我更深入地思考这个问题。
The problem has to do with lifetimes, it seems.问题似乎与生命有关。 I apologize for not showing the entire code, i thought the snippets i shared would describe the problem sufficiently, but in hindsight it does make sense that the context would be important with Rust's lifetimes at play.
我很抱歉没有展示整个代码,我认为我分享的片段会充分描述问题,但事后看来,上下文对 Rust 的生命周期很重要确实是有道理的。
I did find a "solution" for this particular instance of the problem.我确实为这个特定的问题实例找到了“解决方案”。 Since the code in question will only run once per executable start, i can just
Box::leak
the &'static str
and call it a day.由于有问题的代码在每个可执行文件启动时只会运行一次,我可以只使用
Box::leak
&'static str
并将其称为一天。 Still, i would like to figure out if there's a more general solution which could be used for often-created dynamic strings.不过,我想弄清楚是否有更通用的解决方案可用于经常创建的动态字符串。
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")));
}
Currently i am faced with 2 points of confusion here:目前我在这里面临两个困惑点:
impl From<String> for &str
?impl From<String> for &str
没有impl From<String> for &str
? The compiler claims that one exists for impl From<String> for &mut str
, and i'm not seeing the importance of mut
here.impl From<String> for &mut str
存在一个,我在这里没有看到mut
的重要性。impl From<String> for &str
, would it make sense to somehow discourage the usage of Into<&str>
in the public APIs of libraries? impl From<String> for &str
,那么以某种方式阻止在库的公共 API 中使用Into<&str>
是否有意义? Or maybe the issue is with my build_args_parser function and it's just not an option to offload the work to it as far as Rust is concerned?或者也许问题出在我的 build_args_parser 函数上,就 Rust 而言,它不是将工作卸载给它的选项?
Seems like you're trying to convert a String
into a &'a str
.似乎您正在尝试将
String
转换为&'a str
。 You can do it like this:你可以这样做:
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
}
Here's the signature of the function that we want to call:这是我们要调用的函数的签名:
pub fn about<S: Into<&'b str>>(self, about: S) -> Self
So the about
parameter must implement trait Into<&'b str>
.所以
about
参数必须实现 trait Into<&'b str>
。 According to std::convert::Into
, we know that &'b str
does implement trait Into<&'b str>
.根据
std::convert::Into
,我们知道&'b str
确实实现了特征Into<&'b str>
。 So now we just need a way to convert String
into &'b str
.所以现在我们只需要一种方法将
String
转换为&'b str
。 The std::string::String
tell us that there are two ways: use either s.as_str()
or &*s
. std::string::String
告诉我们有两种方法:使用s.as_str()
或&*s
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.