2014-09-24 72 views
2

我一直运行到这个问题的时候,我不太明白,为什么就不能编译如下:“借来的价值不活足够长的时间”使用'as_slice`

fn foo(bar: &'static str) -> Foo { 
    let caps_off = bar.to_ascii_lower().as_slice(); 
    ... 
} 

错误:borrowed value does not live long enough

我有点理解这里的错误,但我不知道任何其他方式来实现这一点。

我尝试将我的str转换为小写&然后将其转换回str类型。看起来很简单。

我在做什么错在这里&我该如何解决它?

全码:

use std::collections::HashMap; 
use std::ascii::StrAsciiExt; 

struct Foo; 

fn foo(bar: &'static str) -> Foo { 
    let caps_off_ = bar.to_ascii_lower(); 
    let caps_off = caps_off_.as_slice(); 

    let mut my_foos:HashMap<&'static str, Foo> = HashMap::new(); 
    my_foos.insert("hi", Foo); 
    *my_foos.find(&caps_off).clone().unwrap() 
} 

回答

0

你应该张贴您的完整代码我们理解的错误,但在代码中,编译器不能告诉新字符串的生命有多长。 所以尝试:

fn foo(bar: &'static str) -> Foo { 
    let caps_off_ = bar.to_ascii_lower(); 
    let caps_off = caps_off_.as_slice(); 
    ... 
} 

所以caps_off_持有新String对象,而你使用的切片。

编辑:

添加到以前的答案,弗朗西斯只是如何解释,你宣称,该地图的键是&'static str,所以find不会接受不匹配相同签名的密钥。所以你有两个选择1)声明地图为<&str, Foo>没有静态生命期或2)使用find_equiv方法。

希望它有帮助。

+0

请参阅上面的完整代码。这很混乱。有没有一种方法可以手动告诉编译器:“我还没有使用'caps_off'完成”? – goo 2014-09-24 14:44:46

+0

如果你把一个可以编译的代码显示出你的错误,我可以帮你。这一定是关于生命的事情。 – snf 2014-09-24 18:38:30

+0

好吧,当然。请参阅我的编辑。代码应该现在编译 – goo 2014-09-24 21:29:31

2

由于编译器推断的信息,错误很难理解。

caps_off是什么类型的?你没有指定它,所以编译器必须从它的用法中推断出它。这只是一次使用,在此表达

*my_foos.find(&caps_off).clone().unwrap() 

find methodMap trait指定的参数是&K型。您将地图定义为HashMap<&'static str, Foo>,因此K&'static str。因此,该参数的具体类型为&&'static str。参数是&caps_off,所以你正在建立一个参考。编译器推断caps_off的类型必须是&'static str以匹配参数的类型。这是问题。

错误是告诉你caps_off_.as_slice()不能被分配到caps_off,因为借来的片不够长。这是因为bar.to_ascii_lower()返回String,并且该字符串仅在函数调用期间存在。这意味着你不能使用Map.find()这个值。

幸运的是,HashMap上有另一种方法可以解决您的问题:find_equiv。通过使用它,编译器可以推断出caps_off的不同类型,它与您要分配给它的表达式(&'a str)兼容。只要改变最后一行foo使用它:

*my_foos.find_equiv(&caps_off).clone().unwrap() 

事实上,你甚至不需要调用as_slice(),您可以通过Stringbar.to_ascii_lower()直接返回,你不需要定义如果只使用小写字符串一次,则为变量:

*my_foos.find_equiv(&bar.to_ascii_lower()).clone().unwrap() 
相关问题