2013-10-29 15 views
46

Trong ví dụ sau, tôi muốn gán giá trị cho mỗi trường trong cấu trúc trong khai báo các trường. Ngoài ra, nó có hiệu quả mất một tuyên bố bổ sung cho mỗi trường để gán một giá trị cho các trường. Tất cả những gì tôi muốn làm là gán các giá trị mặc định khi cấu trúc được khởi tạo.Có cách nào nhanh hơn/ngắn hơn để khởi tạo biến trong cấu trúc Rust?

Có cách nào ngắn gọn hơn để thực hiện việc này không?

struct cParams { 
    iInsertMax: i64, 
    iUpdateMax: i64, 
    iDeleteMax: i64, 
    iInstanceMax: i64, 
    tFirstInstance: bool, 
    tCreateTables: bool, 
    tContinue: bool, 
} 

impl cParams { 
    fn new() -> cParams { 
     cParams { 
      iInsertMax: -1, 
      iUpdateMax: -1, 
      iDeleteMax: -1, 
      iInstanceMax: -1, 
      tFirstInstance: false, 
      tCreateTables: false, 
      tContinue: false, 
     } 
    } 
} 

Trả lời

73

Bạn có thể cung cấp giá trị mặc định cho cấu trúc của mình bằng cách triển khai đặc điểm Default. Chức năng default sẽ trông như thế new chức năng hiện tại của bạn:

impl Default for cParams { 
    fn default() -> cParams { 
     cParams { 
      iInsertMax: -1, 
      iUpdateMax: -1, 
      iDeleteMax: -1, 
      iInstanceMax: -1, 
      tFirstInstance: false, 
      tCreateTables: false, 
      tContinue: false, 
     } 
    } 
} 

Sau đó bạn có thể nhanh chóng struct bằng cách đưa ra chỉ có giá trị không phải mặc định:

let p = cParams { iInsertMax: 10, ..Default::default() }; 

Với một số thay đổi nhỏ để cấu trúc dữ liệu của bạn, bạn có thể tận dụng lợi thế của việc triển khai mặc định có nguồn gốc tự động. Nếu bạn sử dụng #[derive(Default)] trên cấu trúc dữ liệu, trình biên dịch sẽ tự động tạo một hàm mặc định cho bạn điền vào mỗi trường với giá trị mặc định của nó. Giá trị boolean mặc định là false, giá trị tích phân mặc định là 0.

Giá trị mặc định của số nguyên là 0 là một vấn đề ở đây vì bạn muốn trường số nguyên là -1 theo mặc định. Bạn có thể định nghĩa một kiểu mới thực hiện giá trị mặc định là -1 và sử dụng giá trị đó thay vì i64 trong cấu trúc của bạn. (Tôi chưa thử nghiệm điều đó, nhưng nó sẽ hoạt động).

Tuy nhiên, tôi khuyên bạn nên thay đổi một chút cấu trúc dữ liệu của mình và sử dụng Option<i64> thay vì i64. Tôi không biết ngữ cảnh của mã của bạn, nhưng có vẻ như bạn đang sử dụng giá trị đặc biệt là -1 để biểu thị ý nghĩa đặc biệt "vô hạn" hoặc "không có giá thầu tối đa". Trong Rust, chúng tôi sử dụng Option để thể hiện giá trị hiện tại tùy chọn. Không cần hack -1. Tùy chọn có thể là None hoặc Some(x) trong đó x sẽ là i64 của bạn tại đây. Nó thậm chí có thể là một số nguyên không dấu nếu -1 là giá trị âm duy nhất. Giá trị mặc định là OptionNone, vì vậy với đề nghị thay đổi, mã của bạn có thể trông như thế này:

#[derive(Default)] 
struct cParams { 
    iInsertMax: Option<u64>, 
    iUpdateMax: Option<u64>, 
    iDeleteMax: Option<u64>, 
    iInstanceMax: Option<u64>, 
    tFirstInstance: bool, 
    tCreateTables: bool, 
    tContinue: bool, 
} 

let p = cParams { iInsertMax: Some(10), ..Default::default() }; 
+1

Cảm ơn, tôi có thể đọc nhanh, nhưng tôi sẽ đọc lại để tốt hơn hiểu. Các "tự nhiên" mặc định rằng một số ngôn ngữ sử dụng như tôi tin không, sai, "", vv, sẽ phù hợp với tôi. Tôi hiểu rằng có những tác động rộng lớn hơn "vấn đề" nhỏ của tôi để giải quyết. Khả năng trạng thái ví dụ. "iVal: i64 = 0", sẽ giải quyết nhu cầu rộng hơn của tôi, nhưng tôi đoán điều đó sẽ không xảy ra. "# [Deriving (Default)]" nên giải quyết hầu hết các mong muốn của tôi. Tôi không chắc tại sao tôi sử dụng -1 trong chương trình thử nghiệm của mình, nhưng không cần thiết (lịch sử). Nó sẽ rất hữu ích (IMHO) để có thể gán một giá trị tại chỗ mà trường được xác định. –

+4

@BrianOh, theo cách tiếp diễn, "giá trị mặc định cho trường struct" (tức là một cái gì đó như 'struct Foo {val: i64 = 0}') đã được đề xuất và có thể xuất hiện trong các phiên bản sau. – huon

+0

Sẽ tốt nếu được triển khai IMO - "struct foo {....". Tôi đã thực hiện các thay đổi theo đề xuất của bạn, sử dụng cấu trúc như được viết trong câu hỏi của tôi và với mặc định. Điều đó chắc chắn phù hợp với tôi tốt hơn và ngắn gọn hơn nhiều. Không quen với cú pháp, một vấn đề nhỏ mà tôi đã không biết cú pháp cho TẤT CẢ mặc định. IE: Tôi đã sử dụng "= cParams {iInsertMax: 10, ..Default :: default()};", nhưng tôi thực sự muốn "iInstanceMax" cũng là mặc định. IMO nó sẽ là thích hợp hơn cho "# [deriving (Default)]" là một phần của cấu trúc, nhưng tôi đoán sự thay thế phù hợp với trình biên dịch tốt hơn. –

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