Ich möchte ein Array von 10 leere Vektoren in Rust erstellen, aber [Vec::new(); 10]
funktioniert nicht, da Vec
Copy
nicht implementiert. Wie kann ich das tun, und allgemein gesagt, wie kann ich ein Array durch wiederholtes Aufrufen einer Funktion initialisieren?Wie kann ich ein Array mit einer Funktion initialisieren?
Antwort
Das ist wirklich eine interessante Frage.
Die einzige sichere Lösung, die ich denken kann, ist ein Makro wie dieser
Ich sehe zwei mögliche Ansätze
Erste
Eine einfache Lösung Makro
macro_rules! array {
($v: expr; 1) => ([$v]);
($v: expr; 2) => ([$v, $v]);
($v: expr; 3) => ([$v, $v, $v]);
($v: expr; 4) => ([$v, $v, $v, $v]);
($v: expr; 5) => ([$v, $v, $v, $v, $v]);
// until 32
}
let a = array![Vec::new(); 3];
Es ist ein bisschen ausführlich, aber auch die standard lib verwenden diese Art von Konstrukt.
Zweite
Nach einem Zusammenhang zwischen dieser Frage zu realisieren und other, die ich vorher geantwortet hatte, ich diese Lösung nodrop
extern crate nodrop;
macro_rules! array {
($e: expr; $n:expr) => (
{
use std::mem;
use std::ptr;
use nodrop::NoDrop;
struct ArrayBuilder<T> {
len: usize,
data: *mut T,
}
impl<T> Drop for ArrayBuilder<T> {
fn drop(&mut self) {
unsafe {
while self.len > 0 {
let offset = (self.len as isize) - 1;
self.len -= 1;
ptr::drop_in_place(self.data.offset(offset));
}
}
}
}
let mut v: NoDrop<[_; $n]> = NoDrop::new(unsafe {
mem::uninitialized()
});
// helps type inference for v
if false { v[0] = $e; }
let mut builder = ArrayBuilder {
len: 0,
data: (&mut *v as *mut _) as *mut _
};
unsafe {
for i in 0..$n {
ptr::write(builder.data.offset(i as isize), $e);
builder.len = i + 1;
}
}
builder.len = 0;
v.into_inner()
}
)
}
let a = array![Vec::new(); 3];
Und einen Test, die zeigt mit schrieb, dass es nicht Leckspeicher
#[test]
fn test() {
static mut COUNT: usize = 0;
#[derive(Debug)]
struct X(usize);
impl Drop for X {
fn drop(&mut self) {
println!("drop {:?}", self.0);
}
}
impl X {
fn new() -> X {
unsafe {
if COUNT == 3 {
panic!();
}
let x = X(COUNT);
COUNT += 1;
x
}
}
}
array![X::new(); 6];
}
Bei diesem Test gerät die Methode X::new
in Panik, wenn X(3)
erstellt wird, also müssen X(0)
, X(1)
, X(2)
gelöscht werden.
Andere
Es ist eine unsichere Lösung here.
Wäre es theoretisch möglich, ein Makro zu erstellen, das ein solches Konstrukt für jedes n erzeugen kann? Meine eigenen Versuche wurden durch die Regel der Rostmakros behindert, die sich zu einem einzigen Ausdruck ausweiten, was es schwierig macht, eine variable Anzahl von Ausdrücken innerhalb der eckigen Klammern zu haben. – user3519580
Mit dem aktuellen Makro-System ist es nicht möglich. – malbarbo
- 1. Wie kann ich ein Array initialisieren, ohne es zu kennen?
- 2. Wie sollte ich ein boost :: array initialisieren?
- 3. initialisieren ein Array in einer Struktur
- 4. Wie kann ich ein Array von Zeigern auf Strukturen initialisieren?
- 5. Wie kann ich ein Array als Argument einer Funktion verwenden?
- 6. ein String-Array initialisieren
- 7. NodeJS initialisieren Array innerhalb Funktion
- 8. Wie ändere ich ein Array mit einer Funktion?
- 9. Warum kann ich ein Array nicht initialisieren, indem ich einen Zeiger auf eine Funktion überlasse?
- 10. C#: ein DateTime-Array initialisieren
- 11. Wie kann ich Klassenobjekt mit Parametern initialisieren?
- 12. Wie kann ich ein Array von Zeigern zu einer Struktur in C deklarieren und initialisieren?
- 13. initialisieren ein Array von int mit einer Reihe von Zahlen
- 14. Wie kann ich ein String-Array mit der Länge 0 in Java initialisieren?
- 15. Wie soll ich dieses mehrdimensionale Array initialisieren?
- 16. Wie gebe ich ein Array von einer Funktion zurück?
- 17. Wie gebe ich ein eigenes Array von einer Funktion zurück?
- 18. Wie kann ich ein Array zurückgeben?
- 19. kann ich ein Array außerhalb der Methode initialisieren wie wir ein Mitglied/Feldvariable
- 20. In C, kann ich eine Zeichenfolge in einer Zeigerdeklaration auf die gleiche Weise initialisieren, wie ich eine Zeichenfolge in einer char-Array-Deklaration initialisieren kann?
- 21. Werte von Array in einer Struktur initialisieren
- 22. Wie Array mit benutzerdefinierten Typ initialisieren
- 23. ein Array initialisieren mit dem letzten Element Schlüssel mit ‚0‘
- 24. Kann ich ein Array mit einer Variablen in Java benennen?
- 25. Array mit Variablen initialisieren: Unerwartetes Token +
- 26. Wie initialisieren Array von Klassen?
- 27. Wie kann ich ein Array in ein anderes Array schieben?
- 28. Wie kann ich ein const-Array oder ein variables Array an eine Funktion in C übergeben?
- 29. Wie kann ich linq verwenden, um ein Array von wiederholten Elementen zu initialisieren?
- 30. Wie kann ich ein Datum für NSdate initialisieren?
Können Sie uns zeigen, was Sie versucht haben? Es sollte kein Problem geben, ein Array aus einer Funktion oder einem Vektor zurückzugeben. Welchen hast du probiert und wie? (Ihr Titel sagt Array, Ihre Frage sagt Vektor). –
Whoops, Sie haben Recht - das ist ein Tippfehler – user3519580
Verwandt: [Warum wird die Eigenschaft Kopieren für die Standardinitialisierung (struct valued) benötigt?] (Http://stackoverflow.com/q/27876588/155423) und [Was ist der richtige Weg, um ein Array fester Länge zu initialisieren?] (http://StackOverflow.com/q/31360993/155423). Duplizieren von [Initialisiere ein großes Array fester Größe mit nicht kopierbaren Typen] (http://stackoverflow.com/q/28656387/155423). – Shepmaster