2015-11-09 14 views
5

Mã này biên dịch chính xác. Nó có một số cảnh báo mã không sử dụng, nhưng đó là okay cho bây giờ.Khi nào và cách sử dụng vector tham chiếu

use std::collections::BTreeMap; 

enum Object<'a> { 
    Str(String), 
    Int(i32), 
    Float(f32), 
    Vector(Vec<&'a Object<'a>>), 
    Prim(fn(State) -> State) 
} 

struct State<'a> { 
    named: BTreeMap<String, &'a Object<'a>>, 
    stack: Vec<Object<'a>> 

} 

impl<'a> State<'a> { 
    fn push_int(&mut self, x: i32) { 
     self.stack.push(Object::Int(x)); 
    } 
} 


fn main() { 
    println!("Hello, world!"); 
    let obj = Object::Str("this is a test".to_string()); 
} 

Phần quan trọng của mã này là push_intstack: Vec<Object<'a>>.

Tôi sắp sửa tạo một máy ảo dựa trên stack. Tôi muốn chuyển trạng thái sang các chức năng, có thể lấy nội dung ra khỏi ngăn xếp, điều khiển nội dung và sau đó đặt một số nội dung vào ngăn xếp; trường được đặt tên sẽ giữ các đối tượng được đặt tên.

Tôi có linh cảm tốt hơn nên thay vào đó, ngăn xếp được hiển thị là Vec<&'a Object<'a>>. Cách tôi có nó bây giờ, tôi sợ rằng tôi đang phạm một số lỗi không hiệu quả. Linh cảm của tôi có đúng không?

Phần thứ hai của vấn đề là tôi không biết cách lấy vector của phiên bản tham chiếu để hoạt động. Tạo ra giá trị mới với vòng đời đúng để đẩy lên ngăn xếp không hiệu quả với tôi.

Tôi hơi mơ hồ về vấn đề này, vì vậy nếu tôi không rõ ràng, hãy hỏi tôi các câu hỏi để xóa nội dung.

+0

Bạn muốn 'Vec >>' cho một con trỏ được sở hữu.Bạn không có hiệu quả, trong đó 'Object :: Int' mất nhiều không gian như' Object :: String', nhưng boxing nó chỉ là sẽ làm cho nó tồi tệ hơn (ngay cả khi boxing cho phép đại diện nhỏ gọn hơn). Tôi sẽ thay đổi 'Str (String)' thành 'Str (Box )' và 'Vector >' to 'Vector >>' và để nó ở đó, vì nó loại bỏ những thứ duy nhất giữ 'Object' * quá * lớn. Nó vẫn còn có thể thêm indirection là tồi tệ hơn so với không hiệu quả cho nhỏ hơn (có lẽ là phổ biến hơn) giá trị, mặc dù. – Veedrac

+1

ý của bạn là gì với "không hiệu quả"? Bạn đang yêu cầu làm thế nào để tiết kiệm bộ nhớ hoặc làm thế nào để được performant hơn? Ngoài ra, tôi nghĩ câu hỏi này thuộc về http://codereview.stackexchange.com/ –

+0

@ker Tôi nghĩ rằng tôi có ý nghĩa cả hai; Tôi đã mơ hồ bởi vì tôi không biết đủ để cụ thể hơn. Có, nó có thể đã đi đến codereview; Tôi không chắc lắm. – phil

Trả lời

6

Lý do bạn không thể làm cho nó hoạt động là các cấu trúc không thể có các trường tham chiếu đến các trường khác. (Xem các liên kết hỗ trợ ở dưới cùng.)

Những gì bạn có thể làm, được đặt tất cả các Object s vào số Vec và có HashMap chứa các chỉ mục của các yếu tố được đặt tên mà nó tham chiếu.

struct State { 
    named: BTreeMap<String, usize>, 
    stack: Vec<Object> 
} 

Tôi cũng sẽ xóa tất cả thời gian sống trong ví dụ của bạn, vì điều này có thể được thực hiện hoàn toàn với các đối tượng được sở hữu.

enum Object { 
    Str(String), 
    Int(i32), 
    Float(f32), 
    Vector(Vec<Object>), 
    Prim(fn(State) -> State) 
} 

Bạn có thể thử một việc thực hiện hoạt động trong Playground

liên kết hỗ trợ:

+2

Điểm phong cách liên quan đến "(có, mỗi từ là một liên kết khác)". Một danh sách các liên kết có dấu đầu dòng đến các câu hỏi Stack Overflow khác rõ ràng hơn để duyệt, vì SO sẽ tự động tìm kiếm các tiêu đề và hiển thị chúng. –

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