2016-02-23 16 views
8

Ten kodCzy jest możliwe utworzenie `HashMap` z kluczem typu` * const Any`?

use std::any::Any; 
use std::collections::HashMap; 

fn main() { 
    let x: HashMap<*const Any, i32> = HashMap::new(); 
} 

Daje mi następujący błąd:

error: the trait `core::marker::Sized` is not implemented for the type `core::any::Any` [E0277] 

let x: HashMap<*const Any, i32> = HashMap::new(); 
            ^~~~~~~~~~~~ 

Przede wszystkim nie rozumiem dlaczego narzekają core::any::Any, gdy klawisze są typu *const core::any::Any. Czy nie powinno być rozmiaru niezależnie od tego, na co wskazuje? Aby to sprawdzić, próbowałem:

use std::any::Any; 
use std::mem::size_of; 

fn main() { 
    println!("size_of(*const Any) = {}", size_of::<*const Any>()); 
} 

który, jak się spodziewano, produkuje:

size_of(*const Any) = 16 
+4

FWIW , błąd występuje dla dowolnego wskaźnika do cechy. – Shepmaster

+1

Myślę, że błąd wynika z faktu, że istnieje 'impl Hash dla * const T', ale' T' jest domyślnie wymagane, aby 'Sized', nawet jeśli nie jest to konieczne. –

Odpowiedz

1

To nie jest najładniejszy rozwiązanie, ale tutaj jest to, co wymyśliłem:

use std::any::Any; 
use std::collections::HashMap; 
use std::hash::{Hasher, Hash}; 
use std::cmp; 

struct Wrapper { 
    v: *const Any, 
} 

impl Wrapper { 
    fn get_addr(&self) -> usize { 
     self.v as *const usize as usize 
    } 
} 

impl Hash for Wrapper { 
    fn hash<H: Hasher>(&self, state: &mut H) { 
     self.get_addr().hash(state) 
    } 
} 

impl cmp::PartialEq for Wrapper { 
    fn eq(&self, other: &Self) -> bool { 
     self.get_addr() == other.get_addr() 
    } 
} 

impl cmp::Eq for Wrapper {} 

fn main() { 
    let x: HashMap<Wrapper, i32> = HashMap::new(); 
} 
Powiązane problemy