2016-02-23 12 views
8

Dieser CodeIst es möglich, eine `HashMap` zu erstellen, die mit etwas vom Typ` * const Any` codiert ist?

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

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

gibt mir die folgende Fehlermeldung:

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

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

Zunächst einmal verstehe ich nicht, warum es core::any::Any beschweren sich über, wenn die Schlüssel von *const core::any::Any Typ sind. Sollte nicht *const _ Größe unabhängig davon, was es zeigt auf? Um dies zu testen, habe ich versucht:

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

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

die, wie erwartet, produziert:

size_of(*const Any) = 16 
+4

FWIW Der Fehler tritt bei jedem Zeiger auf ein Merkmal auf. – Shepmaster

+1

Ich denke, der Fehler kommt von der Tatsache, dass es ein 'impl Hash für * const T' gibt, aber' T' wird implizit benötigt, um 'Sized' zu sein, obwohl es unnötig ist. –

Antwort

1

Es ist nicht die schönste Lösung, aber hier ist, was ich kam mit:

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(); 
} 
Verwandte Themen