[英]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.