2016-01-12 16 views
5

Tôi có một chức năng giống như:sửa đổi 'iter` chuỗi để sử dụng `and_then`, vv

type Attributes = HashMap<String, json::Json>; 
type Store = Arc<RwLock<HashMap<String, RwLock<Attributes>>>>; 

fn get(store: &Store, key: &str) -> Option<Attributes> { 
    store.read().iter() 
     .filter_map(|g| (*g).get(key)) 
     .filter_map(|v| v.read().ok()) 
     .map(|v| (*v).clone()) 
     .next() 
} 

này biên dịch và làm việc tốt. Tuy nhiên, đối với sự soi sáng của riêng tôi, tôi đã cố gắng để thay đổi này để sử dụng tiêu chuẩn Result/Option phương pháp (mà không chuyển đổi các LockResult một Iter), một cái gì đó như:

store.read().ok() 
    .and_then(|g| (*g).get(key)) 
    .and_then(|v| v.read().ok()) 
    .map(|v| (*v).clone()); 

Nhưng điều này nói với tôi rằng g does not live long enough. Tôi đã thử thêm refas_ref ở những nơi khác nhau, nhưng không thể làm cho nó biên dịch. Tôi đang thiếu gì?

Tôi biết tôi có thể lấy nó để làm việc như:

store.read().ok() 
     .and_then(|g| { 
      (*g).get(key) 
       .and_then(|v| v.read().ok()) 
       .map(|v| (*v).clone()) 
     }) 

Nhưng tôi muốn để có thể chuỗi nó như thế nào trong trường hợp iter.

+0

(Câu hỏi có khả năng noob) Đây không phải là sự khác biệt giữa 'iter()' và 'into_iter()'? Bạn có thể muốn sử dụng 'into_iter()' để chuyển quyền sở hữu cho phần còn lại của chuỗi để các tham chiếu của bạn tồn tại trong suốt? –

+0

@SimonWhitehead, cảm ơn nhận xét! Có, tôi nghĩ rằng đây chính xác là sự khác biệt giữa 'iter' và' into_iter' - nhưng ngược lại. I ** do ** muốn sử dụng 'iter' thay vì' in_iter', và trên thực tế, tôi muốn một biến 'and_then' thực hiện một cái gì đó giống như' iter', nhưng tôi không thể tìm ra kết hợp đúng của 'as_ref' , v.v., thực hiện điều này. Khi tôi thay đổi ví dụ đầu tiên ở trên để sử dụng 'in_iter', tôi nhận được các thông báo lỗi giống như ví dụ thứ hai của tôi. –

+0

Tôi không cho rằng bạn có thể đặt cùng một MVCE trên playpen cho tôi/những người khác để tinker với? –

Trả lời

3

OK, trình biên dịch thực sự gây rối với tôi tối nay.

Tôi có câu thần chú này để biên dịch:

fn get(store: &Store, key: &str) -> Option<Attributes> { 
    let r = store.read(); 
    let x = r.as_ref().ok() 
     .and_then(|g| (*g).get(key)) 
     .and_then(|v| v.read().ok()) 
     .map(|v| (*v).clone()); 
    x 
} 

Nếu bạn inline hoặc r hoặc x, bạn sẽ nhận được một lỗi does not live long enough một lần nữa. Tôi không chắc tại sao, vì về nguyên tắc, bảo vệ khóa nên duy trì trạng thái hoạt động tạm thời cho đến khi kết thúc tuyên bố.

Các vấn đề liên quan