Bu, özellikle daha yüksek sıra ömürleri olan higher rank trait bounds gerektirir. Tam tekdüzen sözdizimi F: for<'a> FnOnce<(&'a mut Builder,),()>
olur.
Bir ömür boyu kullanımda işlev kullanılamaz, örn. Biz
pub fn build<'b, F>(rules: F) -> Builder where F: FnOnce<(&'b mut Builder,),()>
olsaydı bu build
eser ne olursa olsun ömür boyu birlikte arayanın istediği söylüyor (örneğin onlar 'b
== 'static
seçti olabilir), ancak kullanılması gerekirse, belirli bir beton ömrü olduğundan bu, geçersiz : fonksiyonun içinde &mut builder
'un ömrü. F: for<'a> ...
bir sınırda kullanıldığında F
herhangi bir ömür boyu 'a
ile çalıştığı için derleyici &mut builder
'dan birinin yerine yasal olduğunu görür.
Yukarıda belirtildiği gibi, bu gerçekten çirkin bir çift sözdizimi. Bunun daha güzel hale getirilebilmesi için birbirini izleyen iki yol var. İlk olarak, kapanma özelliklerini kullanmanın kuralsal yolu ()
şekeri: for<'a> FnOnce(&'a mut Builder) ->()
, ya da Rust'un geri kalanıyla olduğu gibi, ->()
atılabilir: for<'a> FnOnce(&'a mut Builder)
. (. NB bu FnOnce<...>
için sadece şeker, ama sadece şekerli sözdizimi 1.0'da bu özelliklerin etkileşim için stabilize edilir.)
Sonra parantez sözdizimi biraz ekstra kuralı vardır: otomatik for<'a>
gibi hareket ömür ekler (özellikle, for
öğesinin içine yerleştirilmiş herhangi bir ömür boyu ile lifetime elision geçer), bu nedenle yalnızca F: FnOnce(&mut Builder)
F: for<'a> FnOnce(&'a mut Builder)
eşdeğerdir ve önerilen sürümdür.
sizin playpen örneğe bu düzeltmeleri uygulamak:
pub fn initialize_with_closure<F>(rules: F) -> uint where F: FnOnce(&mut uint) {
let mut i = 0;
rules(&mut i);
i
}
// equivalently
pub fn initialize_with_closure_explicit<F>(rules: F) -> uint where F: for<'a> FnOnce(&'a mut uint) ->() {
let mut i = 0;
rules(&mut i);
i
}
pub fn main() {
initialize_with_closure(|i: &mut uint| *i = *i + 20);
initialize_with_closure_explicit(|i: &mut uint| *i = *i + 20);
}
playpen
Yakın seçmen: neden bu offtopic? – huon