2016-03-01 16 views
8

herhangi ömrü ile türlerine referansları üzerinde çalışabileceği bir kutulu kapatılması dönen bir fonksiyon yazmaya çalışıyorum kutulu. Belirli bir örneği yazarken her şey iyi çalışıyor. Ancak jenerik bir sürümü yazarken, ömür boyu problemlerle karşılaşıyorum. kapatma bunun daha uzun yaşamak için türü parametresi ihtiyacı nedenRanked Sürekli Bağlı ve kapanışları ömür sorunu

struct Parameter<'a> { 
    s: &'a str, 
} 

fn main() { 
    let closure = generate_closure_gen(); 
    let string = String::from("Hello World!"); 
    let parameter = Parameter { s: &string }; // Error: string does not live long enough 
    closure(&parameter); 
} 

// This one works fine 
// Desugared version for Box<Fn(&Parameter)> 
fn generate_closure() -> Box<for <'a, 'r> Fn(&'r Parameter<'a>)> { 
    Box::new(|c: &Parameter| {}) 
} 

// This one gives lifetime errors 
fn generate_closure_gen<C>() -> Box<Fn(&C)> { 
    Box::new(|c: &C| {}) 
} 

Ben (depolama ya da bir şey yoktur ...) görmüyorum. Ve HRTB ile genel olmayan sürümü için çalışır, sadece genel sürümü ile çalışmak için mümkün olması gerektiğini hissediyor. Ben genel sürümünü kullanarak belirli bir sürümünü yazmaya çalışırsanız
Ayrıca, bir tür hatayı

// Desugared version for Box<Fn(&Parameter)> 
fn generate_closure_2() -> Box<for <'a, 'r> Fn(&'r Parameter<'a>)> { 
    generate_closure_gen() 
} 

src/main.rs:22:5: 22:27 error: mismatched types: 
expected `Box<for<'r, 'r> core::ops::Fn(&'r Parameter<'r>) + 'static>`, 
    found `Box<for<'r> core::ops::Fn(&'r _) + 'static>` 
(expected concrete lifetime, 
    found bound lifetime parameter) [E0308] 
src/main.rs:22  generate_closure_gen() 
        ^~~~~~~~~~~~~~~~~~~~~~ 
src/main.rs:22:5: 22:27 help: run `rustc --explain E0308` to see a detailed explanation 

bu işi yapmak konusunda herhangi bir fikir edinmek?

(playpen link)

+1

derleyici genel parametre verildiğinde kendiliğinden '' <'a> için eklemek görünmüyor. Herhangi bir tatmin edici açıklama almazsanız, bu soruna bir bağlantı göndermek isteyebilirsiniz: https://www.reddit.com/r/rust/, Rust geliştiricilerinin asılması daha olasıdır. –

+0

Cevabım açıkçası yanlıştı, dolayısıyla onu sildim. Ama yorumunuz tam olarak ne demek istediğinizi açıklıyor: "Kapatma neden daha uzun yaşamak için type parametresine ihtiyaç duyduğunu anlamıyorum (depolama veya başka bir şey yok ...) Ve genel olmayan sürüm için çalışıyor HRTB ile, sadece jenerik versiyon ile çalışmasını sağlamak mümkün gibi hissediyor. " - @Vaelden – aSpex

cevap

6

Tipi parametreleri bir ömür bağlı bulunmaktadır. Bu ömür boyu, uygulayıcının yaşam boyu parametrelerinin en kısa olanıdır. Sen generate_closure_gen üzerine atlanmış, bu yüzden derleyici İma, ama biz açıkça yazdım eğer, fonksiyon tanımı şu şekilde görünecektir: gerçi

fn generate_closure_gen<'a, C: 'a>() -> Box<Fn(&C)> { 
    Box::new(|c: &C| {}) 
} 

sorunumuzu çözmez Bu değişikliği yapmak. Biz C olmak anlaşılmaktadır anlamaya neden ihtiyaç,

anlamak için. Bir &'y Parameter<'x> ile kapatılması arama ve kapatma for<'b> &'b C kabul eder, böylece C Parameter<'x> olduğunu. Parameter<'x>'un, ömür boyu C'a bağlı bir etkisi olacak bir ömür boyu parametresi vardır. Jenerik fonksiyonlarda

Ömür parametreleri işlev çağrısı önce başlar ömürleri ile ikame edilmelidir. Bu durumda, bu biz kapatılmasına geçen herhangi C yaşam boyu generate_closure_gen çağrısı önce geçerli olması gerektiği anlamına gelir. Bunun nedeni, C'un belirli bir kullanım ömrüne bağlı olmasıdır; yani, CParameter<'x> olduğu zaman, 'x önceden bilinmelidir; Kapatma dediğimiz her seferinde farklı bir 'x'a sahip olamayız.

fn generate_closure_gen<C: for<'a> 'a>() -> Box<Fn(&C)> { 
    Box::new(|c| {}) 
} 

Ama ne yazık ki, o Rust 1.7 itibariyle yasal değildir: Diğer bir deyişle, ne olmasını istiyorum böyle bir şeydir.

İlgili konular