2016-07-05 10 views
4

Kann der folgende C# -Code nach Rust übersetzt werden?Gibt es in C# ein Rust-Äquivalent zu `dynamic`?

dynamic x = 109; 
x = "Hi"; 

Ich frage nach einem allgemeinen dynamischen Typ, um das Erstellen eines Arrays von dynamischen Werten zu ermöglichen. Zum Beispiel:

var l = new dynamic[2]; 
l[0] = 102; 
l[1] = "Hi"; 
+0

Ihre Bearbeitung würde dies zu einem Duplikat von [Was ist der beste Weg, um eine heterogene Sammlung von Objekten zu erstellen?] (Http://stackoverflow.com/questions/27957103/what-is-the-best-way-to -Erstelle-eine-heterogene-Sammlung von Objekten). – Shepmaster

+0

Müssen Sie tatsächlich jeden Typ oder nur eine geschlossene Vereinigung von Typen zulassen (z. B. "int" oder "string")? – Lee

+0

@Lee Irgendein Typ ... – TuxCopter

Antwort

4

Eine Möglichkeit ist, einen Vektor von Any zu verwenden (Link zur Beta, weil die stabilen docs für Any definiert ist, nicht die Methoden zeigen, aber sie sind stabil):

use std::any::Any; 

fn main() { 
    let mut v: Vec<Box<Any>> = vec![]; 
    v.push(Box::new(102usize)); 
    v.push(Box::new("Hi")); 

    for item in &v { 
     // to do an operation, it is necessary to downcast to 
     // a concrete type 
     if let Some(x) = item.downcast_ref::<usize>() { 
      println!("num = {:?}", x) 
     } 
    } 
} 

Beachten Sie, dass, im Gegensatz zu dynamic in C#, von dem angenommen wird, dass er jede Operation unterstützt, unterstützt ein Wert vom Typ Any (Box<Any>) nur die in Any (Box<Any> und Any) definierten Operationen. Ein Downcast ist erforderlich, um eine Methode des konkreten Typs aufzurufen.


Ich denke, dass es nicht möglich ist, eine Art wie dynamic von C# in Rust zu haben. Um das Aufrufen einer beliebigen Methode für einen dynamischen Wert zu unterstützen, ist eine (vollständige) Laufzeit-Reflektionsunterstützung erforderlich, die von Rust nicht bereitgestellt wird.

Wenn Sie die Methoden kennen, die aufgerufen werden, dann ist die beste Option, ein Merkmal zu definieren und Box<Trait> zu verwenden (Any ist in diesem Fall nicht erforderlich).

+0

Ah, ich war gerade dabei, das zu aktualisieren. Beachten Sie, dass Sie nicht zu einem Objektmerkmal springen können, sodass Sie beispielsweise "keinen druckbaren Typ" erhalten. Stimmt immer noch nicht mit "dynamisch" überein, weil Sie nicht einfach irgendeine beliebige Methode aufrufen können. – Shepmaster

3

Nicht direkt. Sie können einfach eine neue Bindung für x erstellen:

fn main() { 
    let x = 109; 
    let x = "Hi"; 
} 

auf Ihrem Anwendungsfall abhängig, könnten Sie in der Lage sein, ein generic durch ein Merkmal oder ein Merkmal Objekt begrenzt verwenden ähnliche Ziele zu erreichen:

use std::fmt::Display; 

fn main() { 
    let mut x: Box<Display> = Box::new(109); 
    x = Box::new("Hi"); 
} 

jedoch die C# docs state:

Beim Kompilieren ein Element Das heißt, dass "dynamisch" jede Operation unterstützt.

Dies gilt nicht für ein Merkmalobjekt; Ein Merkmalobjekt kann nur für die expliziten Methoden im Merkmal verwendet werden. Ich habe nicht festgestellt, dass dies eine wesentliche Hürde in dem Code ist, den ich geschrieben habe. Im Allgemeinen gibt es eine feste Anzahl von Methoden, die ich aufrufen möchte, so dass es möglich ist, diese einem Merkmal zuzuordnen. In anderen Fällen kann ich einen generischen Typ angeben, damit der Benutzer einen Typ angeben kann, der zu ihrem Fall passt.