簡體   English   中英

Rust中的內置對象

[英]A built-in Object in Rust

Rust沒有內置的Object類型嗎? 如果是這樣的話,我該如何創建一個在Java中將成為Object的“某物”的HashMap:

  fn method1(my_hash_map: HashMap<&str, ???>) { ... } // Rust
  void method1(Map<String, Object> myMap) { ... } // Java

如果您想要一個HashMap可以混合許多不同類型的值,則必須使用Any Map<String, Object>最直接等效的是HashMap<String, Box<Any>> 我將&str切換為String因為沒有生命周期的&str可能不是您想要的,並且無論如何甚至比Rust的String更能從Java String刪除。

但是,如果您根本不關心值的類型,則使method1泛型更為簡單和有效:

fn method1<T>(my_hash_map: HashMap<String, T>) { ... }

當然,您也可以添加約束T:Trait以使用值來做更多有趣的事情(參見Object允許相等比較和哈希)。

為了擴大對rightføld的評論,Rust中確實可以找到最接近的Any ,盡管它確實有一個主要限制:它只能由滿足'static生存期'static的類型實現。 也就是說,您不能將任何包含非靜態引用的類型都視為Any

第二個復雜之處是Java中的Object具有引用語義,並為您提供了共享所有權。 因此,您需要Rc<RefCell<Any>>東西來獲得大致可比的東西。 但是請注意, 強烈建議不要這樣做,因為它基本上會將許多檢查移至運行時。 這樣的事情應該是萬不得已的后備。

最后,值得注意的是,只要我知道,有沒有辦法做到上一個動態上溯造型Any比擦除類型其他任何東西; 因此您不能引用實現了Show的值,將其轉換為&Any ,然后轉換為&Show

更好的選擇(如果適用)包括對值類型進行一般化(因此,請使用泛型函數和結構),如果要支持的類型是固定的有限類型列表,或者按該順序編寫和實現自定義特性,則使用enum

為了給您一個使用Any的示例,我將以下內容結合在一起。 請注意,我們必須嘗試顯式上載到每種受支持的類型。

#![feature(if_let)]

use std::any::{Any, AnyRefExt};
use std::collections::HashMap;

fn main() {
    let val_a = box "blah";
    let val_b = box 42u;
    let val_c = box 3.14159f64;

    let mut map = HashMap::new();
    map.insert("a".into_string(), val_a as Box<Any>);
    map.insert("b".into_string(), val_b as Box<Any>);
    map.insert("c".into_string(), val_c as Box<Any>);

    println!("{}", map);
    splang(&map);
}

fn splang(map: &HashMap<String, Box<Any>>) {
    for (k, v) in map.iter() {
        if let Some(v) = v.downcast_ref::<&str>() {
            println!("[\"{}\"]: &str = \"{}\"", k, *v);
        } else if let Some(v) = v.downcast_ref::<uint>() {
            println!("[\"{}\"]: uint = {}", k, *v);
        } else {
            println!("[\"{}\"]: ? = {}", k, v);
        }
    }
}

運行時,它輸出:

{c: Box<Any>, a: Box<Any>, b: Box<Any>}
["c"]: ? = Box<Any>
["a"]: &str = "blah"
["b"]: uint = 42

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM