2015-03-03 17 views
5

Tôi có một tập hợp các hàm trong mô-đun cần quyền truy cập vào một số trạng thái thời gian khởi tạo được chia sẻ. Hiệu quả Tôi muốn để mô hình này với một vector có thể thay đổi tĩnh như:Phân tích dữ liệu thành biến tĩnh có thể thay đổi mô-đun

static mut defs: Vec<String> = vec![]; 

fn initialize() { 
    defs.push("One".to_string()); 
    defs.push("Two".to_string()); 
} 

(Ví dụ: http://is.gd/TyNQVv, không thành công với "tĩnh học có thể thay đổi không được phép có destructors".)

Câu hỏi của tôi cũng tương tự như Is it possible to use global variables in Rust?, nhưng sử dụng Vec (nghĩa là loại có hàm hủy), vì vậy giải pháp dựa trên Option cho câu hỏi đó dường như không áp dụng. Cụ thể, điều này không thành công với các lỗi tương tự như nỗ lực đầu tiên của tôi:

static mut defs: Option<Vec<String>> = None; 

fn initialize() { 
    let init_defs = vec![]; 
    init_defs.push("One".to_string()); 
    init_defs.push("Two".to_string()); 
    defs = Some(init_defs); 
} 
  1. Có cách nào để có được quyền truy cập vào một tĩnh ("toàn cầu") vector được dân cư lúc khởi tạo và có thể nhìn thấy khi chạy?

  2. Có các mẫu khác mà tôi nên cân nhắc để hỗ trợ trường hợp sử dụng này không? Việc chuyển các tham chiếu rõ ràng tới vectơ trạng thái là có thể, nhưng sẽ làm lộn xộn lên một số lượng lớn các chữ ký hàm mà tất cả đều cần truy cập vào trạng thái này.

Trả lời

9

Bạn có thể sử dụng lazy_static cho mục đích này:

lazy_static! { 
    static ref defs: Vec<String> = { 
     let mut init = vec!["One".to_string(), "Two".to_string()]; 
     // init.push(...); etc. etc. 
     init 
    } 
} 

Đó initialises một vector về việc tiếp cận đầu tiên, và nó là không thay đổi sau đó. Nếu bạn muốn sửa đổi nó sau này, gói nó trong một std::sync::Mutex là một bước đầu tiên tốt.

Có các mẫu nào khác mà tôi nên cân nhắc để hỗ trợ trường hợp sử dụng này không? Việc chuyển các tham chiếu rõ ràng tới vectơ trạng thái là có thể, nhưng sẽ làm lộn xộn lên một số lượng lớn các chữ ký hàm mà tất cả đều cần truy cập vào trạng thái này.

Một mẫu để xem xét là tạo đối tượng ngữ cảnh lưu trữ tất cả thông tin mà các chức năng cần, ví dụ:

struct Context { 
    defs: Vec<String> 
} 

và sau đó đi qua xung quanh Context đảm bảo mọi người đều biết những gì họ cần biết. Bạn thậm chí có thể xem xét đặt tất cả/nhiều/một số hàm làm phương thức trên Context, ví dụ:

impl Context { 
    fn foo(&self) { 
     if self.defs.len() > 10 { 
      println!("lots of defs"); 
     } 
    } 
    // ... 
} 

Mẫu này đặc biệt tốt nếu bạn cần sửa đổi bối cảnh (tự động đảm bảo an toàn luồng) và/hoặc nếu bạn muốn có một số trường hợp độc lập trong một quy trình.

+1

Cảm ơn! Điều này trả lời cả hai câu hỏi của tôi rất rõ ràng. Tôi đặc biệt thích mẫu struct Context, với các phương thức 'impl''d on. Điều đó cảm thấy thành ngữ hơn. – Bosh

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