2014-11-17 11 views
7

Mam otokę typu new dookoła tablicy. Zakładałem, że mogę użyć size_of zamiast ręcznie przesuwać rozmiar tablicy, ale kompilator uważa, że ​​się mylę.Deklarowanie tablicy przy użyciu stałego wyrażenia dla jej rozmiaru

use std::mem::{size_of, size_of_val}; 

#[repr(C, packed)] 
struct BluetoothAddress([u8, ..6]); 

fn main() { 
    const SIZE: uint = size_of::<BluetoothAddress>(); 

    let bytes = [0u8, ..SIZE]; 
    println!("{} bytes", size_of_val(&bytes)); 
} 

(playpen link)

Używam nightly: rustc 0.13.0-nightly (7e43f419c 2014-11-15 13:22:24 +0000)

Kod ten nie powiedzie się z następujący błąd:

broken.rs:9:25: 9:29 error: expected constant integer for repeat count, found variable 
broken.rs:9  let bytes = [0u8, ..SIZE]; 
            ^~~~ 
error: aborting due to previous error 

Rust Reference on Array Expressions sprawia, że ​​myślę, że to powinno działać:

In the [expr ',' ".." expr] form, the expression after the ".." must be a constant expression that can be evaluated at compile time, such as a literal or a static item.

Odpowiedz

6

Twoja definicja SIZE nie jest legalna; po prostu błędy w nim występują później niż błąd w konstrukcji tablicy. Jeżeli zmienisz [0u8, ..SIZE] do [0u8, ..6] tak, że ta część działa, można znaleźć problemy z deklaracją SIZE:

<anon>:7:24: 7:53 error: function calls in constants are limited to struct and enum constructors [E0015] 
<anon>:7  const SIZE: uint = size_of::<BluetoothAddress>(); 
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
<anon>:7:24: 7:51 error: paths in constants may only refer to items without type parameters [E0013] 
<anon>:7  const SIZE: uint = size_of::<BluetoothAddress>(); 
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Po prostu nie można nazwać size_of takiego w chwili obecnej.

Alternatywą jest odwrócić rzeczy tak, że SIZE jest kanoniczny definicja i innych miejsc używać go:

use std::mem::{size_of, size_of_val}; 

const SIZE: uint = 6; 

#[repr(C, packed)] 
struct BluetoothAddress([u8, ..SIZE]); 

fn main() { 
    let bytes = [0u8, ..SIZE]; 
    println!("{} bytes", size_of_val(&bytes)); 
} 

Aktualizacja: z rdzy 1.0, kwestia ta została skutecznie zastąpiona, a komunikaty o błędach kompilatora zostały poprawione, dzięki czemu są jeszcze bardziej wyraźne.

Ponadto z #42859 niedawno wylądował rustc nightly pozwoli użyciu size_of w stałym związku, pod warunkiem, że paka ma #![feature(const_fn)] (i kiedy #43017 ziemie, które nie będą już potrzebne albo, a następnie będzie przefiltrować przez do stabilny).

Innymi słowy, ulepszenia w języku sprawiły, że nie jest to już problemem.

+1

Czy istnieje problem RFC lub GitHub dla konstruktu sizeof, który działa w czasie kompilacji? – rraval

+1

@rraval: istnieje ogólna potrzeba oceny funkcji Compile-Time, jednak nie jest to coś na 1.0, na czym obecnie się skupiamy. Chociaż 'size_of' może być wyjątkowe, może nie być tego warte. –

+0

Jest tutaj ograniczona liczba RFC, ale jest całkiem pusta: https://github.com/rust-lang/rfcs/issues/322 – Quartz

Powiązane problemy