2014-09-24 65 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() 
相關問題