= Bucket::new(); let node = Node::new(0); bucket.insert(node); // And borrow it back to use it... let node_ptr = bucket.get(&0).unwrap(); node_ptr.send("hi!")
node... let mut udp_bucket = Bucket::new(); let udp_node = UdpNode::new(0); udp_bucket.insert(udp_node, 0); Or the other let mut bluetooth_bucket = Bucket::new(); let bluetooth_node = BluetoothNode::new(1); bluetooth_bucket.insert(bluetooth_node, 1);
too flexible: bucket.insert("I'm not a node".to_string(), 0) • Can't use any functions of the node structs since compiler can't know what type they are, other than N • A bucket can contain only one of any kind of struct
node... let mut udp_bucket = Bucket::new(); let udp_node = UdpNode::new(0); udp_bucket.insert(udp_node); Or the other let mut bluetooth_bucket = Bucket::new(); let bluetooth_node = BluetoothNode::new(1); bluetooth_bucket.insert(bluetooth_node);
that impl Node • Can call methods that trait Node declares: node.address() • A bucket can still only contain one type of thing that impements Node Heterogeneous potential, homogeneous usage
bucket let mut bucket = Bucket::new(); let udp_node = UdpNode::new(0); let bluetooth_node = BluetoothNode::new(1); bucket.insert(Box::new(udp_node)); bucket.insert(Box::new(bluetooth_node)); We can borrow and use both kinds because they impl Node bucket.get(&0).unwrap().send("Sending with UDP node"); bucket.get(&1).unwrap().send("Sending with Bluetooth node");
Can call methods that trait Node declares • One bucket can store any mixture of things that imple Node • Anything borrowed from the bucket must be treated as a Node. Compiler can't know what kind of object was actually borrowed, just the trait.
more efficient • Can lead to code "bloat" due to specific function for each type • Aggressive compiler "optimization" can actually lead to slower performance by bloating instruction cache • Rust stdlib prefers static-dispatch when possible
let ptr: [size] = # print_fancy(size) // 16 bits let num = [x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x]; let ptr: [size] = # print_fancy(size) // ptrs are all the same size :)
boxed = Box::new(10u8) as Box<Fancy>; let shared_reference = &10u8 as &Fancy; let mut_reference = &mut 10u8 as &mut Fancy; let raw_pointer = &10u8 as *const Fancy; let mut_raw_pointer = &mut 10u8 as *mut Fancy;
= &numbers as &Clone; --> src/dispatch.rs:61:40 | 61 | let trait_object = &numbers as &Clone; | ^^^^^^ the trait `std::clone::Clone` cannot be made into an object | = note: the trait cannot require that `Self : Sized`