我想为具有生存期参数的 struct 实现FromStr:

use std::str::FromStr;

struct Foo<'a> {
    bar: &'a str,
}

impl<'a> FromStr for Foo<'a> {
    type Err = ();
    fn from_str(s: &str) -> Result<Foo<'a>, ()> {

        Ok(Foo { bar: s })
    }
}

pub fn main() {
    let foo: Foo = "foobar".parse().unwrap();
}

然而,编译器抱怨:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/main.rs:11:12
   |
11 |         Ok(Foo { bar: s })
   |            ^^^
   |
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Foo<'a>, ()>
  --> src/main.rs:9:5
   |
9  |     fn from_str(s: &str) -> Result<Foo<'a>, ()> {
   |     ^

将impl更改为

impl<'a> FromStr for Foo<'a> {
    type Err = ();
    fn from_str(s: &'a str) -> Result<Foo<'a>, ()> {
        Ok(Foo { bar: s })
    }
}

给出了这个错误

error[E0308]: method not compatible with trait
  --> src/main.rs:9:5
   |
9  |     fn from_str(s: &'a str) -> Result<Foo<'a>, ()> {
   |     ^ lifetime mismatch
   |
   = note: expected type `fn(&str) -> std::result::Result<Foo<'a>, ()>`
   = note:    found type `fn(&'a str) -> std::result::Result<Foo<'a>, ()>`
note: the anonymous lifetime #1 defined on the block at 9:51...
  --> src/main.rs:9:52
   |
9  |     fn from_str(s: &'a str) -> Result<Foo<'a>, ()> {
   |                                                    ^
note: ...does not necessarily outlive the lifetime 'a as defined on the block at 9:51
  --> src/main.rs:9:52
   |
9  |     fn from_str(s: &'a str) -> Result<Foo<'a>, ()> {
   |                                                    ^
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Foo<'a>, ()>
  --> src/main.rs:9:5
   |
9  |     fn from_str(s: &'a str) -> Result<Foo<'a>, ()> {
   |     ^

Playpen

推荐答案

我不相信你能在这种情况下实现FromStr.

fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err>;

trait 定义中没有任何东西将输入的生存期与输出的生存期联系起来.

Not a direct answer,但我建议创建一个接受引用的构造函数:

struct Foo<'a> {
    bar: &'a str
}

impl<'a> Foo<'a> {
    fn new(s: &str) -> Foo {
        Foo { bar: s }
    }
}

pub fn main() {
    let foo = Foo::new("foobar"); 
}

这样做的另一个好处是,不存在任何故障模式——无需设置unwrap.

您也可以只实施From:

struct Foo<'a> {
    bar: &'a str,
}

impl<'a> From<&'a str> for Foo<'a> {
    fn from(s: &'a str) -> Foo<'a> {
        Foo { bar: s }
    }
}

pub fn main() {
    let foo: Foo = "foobar".into();
}

Rust相关问答推荐

生成的future 的 struct 是什么?

当一个箱子有自己的依赖关系时,两个人如何克服S每箱1库+n箱的限制?

如果LET;使用布尔表达式链接(&Q);

新创建的变量的绑定生存期

为什么 tokio 在以奇怪的方式调用时只运行 n 个任务中的 n-1 个?

可选包装枚举的反序列化

如何在 Rust 中打印 let-else 语句中的错误?

Rust 如何返回大类型(优化前)?

当没有实际结果时,如何在 Rust 中强制执行错误处理?

存储返回 impl Trait 作为特征对象的函数

闭包返回类型的生命周期规范

trait 对象指针的生命周期

max(ctz(x), ctz(y)) 有更快的算法吗?

为什么 Rust 的临时值有时有参考性有时没有?

Rust:`sort_by` 多个条件,冗长的模式匹配

在 FFI 的上下文中,未初始化是什么意思?

你能告诉我如何在 Rust 中使用定时器吗?

如何异步记忆选项中的 struct 字段

Rust HRTB 是相同的,但编译器说一种类型比另一种更通用

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?