-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathdyn.alu
64 lines (57 loc) · 1.76 KB
/
dyn.alu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
protocol Slot<Self, Element> {
fn get(self: &Self) -> Option<Element>;
fn set(self: &mut Self, element: Element);
fn type_name(self: &Self) -> &[u8] {
std::typing::type_name::<Self>()
}
}
struct RealSlot {
value: Option<i32>,
}
impl RealSlot {
fn get(self: &RealSlot) -> Option<i32> {
self.value
}
fn set(self: &mut RealSlot, element: i32) {
self.value = Option::some(element);
}
mixin Slot<RealSlot, i32>;
}
struct NullSlot {}
impl NullSlot {
fn get(self: &NullSlot) -> Option<i32> {
Option::none()
}
fn set(self: &mut NullSlot, _element: i32) {
}
mixin Slot<NullSlot, i32>;
}
/// Static polymorphism.
///
/// During monomorphization, the compiler will generate a copy of `roundtrip_generic`
/// for each type of slot encountered (RealSlot and NullSlot).
fn roundtrip_generic<T: Slot<T, i32>>(slot: &mut T) {
let val = 42;
println!("[GENERIC] Inserting {} into {}", val, slot.type_name());
slot.set(val);
println!("[GENERIC] Retrieving value from {}: {}", slot.type_name(), slot.get());
}
/// Dynamic polymorphism.
///
/// `roundtrip_dyn` is a non-generic function. It takes a dyn object, which contains
/// a pointer to a virtual method table so an appropriate implementation of `Slot` can be
/// found at runtime.
fn roundtrip_dyn(slot: &mut dyn Slot<Self, i32>) {
let val = 42;
println!("[DYN] Inserting {} into {}", val, slot.type_name());
slot.set(val);
println!("[DYN] Retrieving value from {}: {}", slot.type_name(), slot.get());
}
fn main() {
let real_slot = RealSlot { value: Option::none() };
let null_slot = NullSlot {};
roundtrip_generic(&real_slot);
roundtrip_generic(&null_slot);
roundtrip_dyn(&real_slot);
roundtrip_dyn(&null_slot);
}