2015-03-08 16 views
3

我想要實現FromStr爲終身參數結構:如何在具體的生命週期中實現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

+0

有什麼理由不只是做一個構造? – Shepmaster 2015-03-08 20:44:28

+0

是的,我在解析器中使用它,在那裏我只持有引用,以便不做任何複製 – 2015-03-08 21:11:01

+1

這是我在http://stackoverflow.com/a/24575591/497043處理的同樣的問題;不可能做你想做的事。 – 2015-03-09 01:08:12

回答

6

我不認爲你可以在這種情況下執行FromStr

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

在特徵定義中沒有任何內容將輸入的生命週期與輸出的生命週期聯繫在一起。

沒有直接回答,但我只是建議作出接受的參考構造:

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(); 
}