Static Dispatch
Objectives: Create container accepting items of any type. Categorize items in runtime. Dispatch methods statically.
Python
Following code works well but I'm unable to give good reasons for doing this in practice. Perhaps performance of this code may be compared with dynamic dispatching. This needs more investigation though.
from typing import Any
class Cat:
def make_sound(self):
print("miao")
class Cow:
def make_sound(self):
print("mooo")
animals: list[Any] = []
animals.append( Cat() )
animals.append( Cow() )
cat_make_sound = Cat.make_sound
cow_make_sound = Cow.make_sound
for animal in animals:
match animal:
case Cat():
cat_make_sound(animal)
case Cow():
cow_make_sound(animal)
CPython interpreters older than 3.10 don't support match
, thus alternative would be:
for animal in animals:
if isinstance(animal, Cat):
cat_make_sound(animal)
elif isinstance(animal, Cow):
cow_make_sound(animal)
Rust
use std::any::Any; trait CanMakeSound { fn make_sound(&self); } struct Cat { } impl CanMakeSound for Cat { fn make_sound(&self) { println!("miao") } } struct Cow { } impl CanMakeSound for Cow { fn make_sound(&self) { println!("mooo") } } fn main() { let mut animals: Vec<Box<dyn Any>> = Vec::new(); animals.push( Box::new(Cat{}) ); animals.push( Box::new(Cow{}) ); for animal in animals { if let Some(cat) = animal.downcast_ref::<Cat>() { cat.make_sound(); } else if let Some(cow) = animal.downcast_ref::<Cow>() { cow.make_sound(); } } }
Crystal
#![allow(unused)] fn main() { class Cat def make_sound puts "miao" end end class Cow def make_sound puts "mooo" end end alias Animal = Cat | Cow alias Any = Pointer(Void) animals = [] of Any animals << Box(Animal).box(Cat.new) animals << Box(Animal).box(Cow.new) animals.each do |animal| unboxed = Box(Animal).unbox(animal) if cat = unboxed.as?(Cat) cat.make_sound elsif cow = unboxed.as?(Cow) cow.make_sound end end }