{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Traits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "// Fill in the two impl blocks to make the code work.\n", "// DON'T modify the code in `main`.\n", "trait Greetings {\n", " fn say_hi(&self) -> String {\n", " String::from(\"Hi\")\n", " }\n", "\n", " fn say_something(&self) -> String;\n", "}\n", "\n", "struct Student {}\n", "\n", "impl Greetings for Student {\n", "}\n", "\n", "struct Teacher {}\n", "\n", "impl Greetings for Teacher {\n", "}\n", "\n", "fn main() {\n", " let s = Student {};\n", " assert_eq!(s.say_hi(), \"Hi\");\n", " assert_eq!(s.say_something(), \"I'm a good student\");\n", "\n", " let t = Teacher {};\n", " assert_eq!(t.say_hi(), \"Hi, I'm your new teacher\");\n", " assert_eq!(t.say_something(), \"I'm not a bad teacher\");\n", "\n", " println!(\"Success!\");\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "struct Fender {}\n", "struct Gibson {}\n", "\n", "trait Guitar {\n", " fn sound(&self) -> String;\n", "}\n", "\n", "impl Guitar for Fender {\n", " fn sound(&self) -> String {\n", " \"like Jimmy!\".to_string()\n", " }\n", "}\n", "\n", "impl Guitar for Gibson {\n", " fn sound(&self) -> String {\n", " \"like Slash!\".to_string()\n", " }\n", "}\n", "\n", "// Returns some struct that implements Guitar, but we don't know which one at compile time.\n", "// FIX the errors here, you can make a fake random, or you can use trait object.\n", "fn random_guitar(random_number: f64) -> impl Guitar {\n", " if random_number < 0.5 {\n", " Fender {}\n", " } else {\n", " Gibson {}\n", " }\n", "}\n", "\n", "fn main() {\n", " let random_number = 0.234;\n", " let guitar = random_guitar(random_number);\n", " println!(\"You've randomly chosen an guitar, and it sounds {}\", guitar.sound());\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3. Trait bound" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "struct Fender {}\n", "struct Gibson {}\n", "\n", "trait Guitar {\n", " fn sound(&self) -> String;\n", "}\n", "\n", "impl Guitar for Fender {\n", " fn sound(&self) -> String {\n", " \"like Jimmy!\".to_string()\n", " }\n", "}\n", "\n", "impl Guitar for Gibson {\n", " fn sound(&self) -> String {\n", " \"like Slash!\".to_string()\n", " }\n", "}\n", "\n", "\n", "// Implement `fn use_guitar` with trait bound in two ways.\n", "fn use_guitar(g: &G) {\n", " println!(\"Sounds {}\", g.sound());\n", "}\n", "\n", "// Implement `fn sum` with trait bound in two ways.\n", "fn sum(x: T, y: T) -> T {\n", " x + y\n", "}\n", "\n", "fn main() {\n", " let g = Fender{};\n", " use_guitar(&g);\n", " assert_eq!(sum(1, 2), 3);\n", "\n", " \n", " println!(\"Success!\");\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "// FIX the errors.\n", "struct Pair {\n", " x: T,\n", " y: T,\n", "}\n", "\n", "impl Pair {\n", " fn new(x: T, y: T) -> Self {\n", " Self {\n", " x,\n", " y,\n", " }\n", " }\n", "}\n", "\n", "impl Pair {\n", " fn cmp_display(&self) {\n", " if self.x >= self.y {\n", " println!(\"The largest member is x = {:?}\", self.x);\n", " } else {\n", " println!(\"The largest member is y = {:?}\", self.y);\n", " }\n", " }\n", "}\n", "\n", "struct Unit(i32);\n", "\n", "fn main() {\n", " let pair = Pair{\n", " x: Unit(1),\n", " y: Unit(3)\n", " };\n", "\n", " pair.cmp_display();\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "5. Array with trait objects" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "trait Guitar {\n", " fn sound(&self);\n", "}\n", "\n", "struct Stratocaster;\n", "\n", "impl Stratocaster {\n", " fn get_name(&self) {\n", " println!(\"Fender Stratocaster\");\n", " }\n", "}\n", "\n", "struct LesPaul;\n", "\n", "impl LesPaul {\n", " fn get_name(&self) {\n", " println!(\"Gibson Les Paul\");\n", " }\n", "}\n", "\n", "impl Guitar for Stratocaster {\n", " fn sound(&self) {\n", " println!(\"{}\", \"Sounds like Jimmy!\");\n", " }\n", "}\n", "\n", "impl Guitar for LesPaul {\n", " fn sound(&self) {\n", " println!(\"{}\", \"Sounds like Slash!\");\n", " }\n", "}\n", "\n", "fn main() {\n", " // // FILL in the blank to make the code work.\n", " let s = Stratocaster{};\n", " let lp1 = LesPaul{};\n", " let blacky = Stratocaster{};\n", "\n", " let guitars: [__; 3]= [__];\n", "\n", " // Iterate through the guitars and make them sound.\n", " todo!();\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "6. &dyn & Box" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "// FILL in the blanks.\n", "trait Draw {\n", " fn draw(&self) -> String;\n", "}\n", "\n", "impl Draw for u8 {\n", " fn draw(&self) -> String {\n", " format!(\"u8: {}\", *self)\n", " }\n", "}\n", "\n", "impl Draw for f64 {\n", " fn draw(&self) -> String {\n", " format!(\"f64: {}\", *self)\n", " }\n", "}\n", "\n", "fn main() {\n", " let x = 1.1f64;\n", " let y = 8u8;\n", "\n", " // Draw x.\n", " draw_with_box(__);\n", "\n", " // Draw y.\n", " draw_with_ref(&y);\n", "\n", " println!(\"Success!\");\n", "}\n", "\n", "fn draw_with_box(x: Box<__>) {\n", " x.draw();\n", "}\n", "\n", "fn draw_with_ref(x: __) {\n", " x.draw();\n", "}\n", "\n", "main();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "7. Static and Dynamic dispatch" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "rust" } }, "outputs": [], "source": [ "\n", "trait Foo {\n", " fn method(&self) -> String;\n", "}\n", "\n", "impl Foo for u8 {\n", " fn method(&self) -> String { format!(\"u8: {}\", *self) }\n", "}\n", "\n", "impl Foo for String {\n", " fn method(&self) -> String { format!(\"string: {}\", *self) }\n", "}\n", "\n", "// IMPLEMENT below with generics. (static polymorphism)\n", "fn static_dispatch...\n", "\n", "// Implement below with trait objects. (dynamic polymorphism)\n", "fn dynamic_dispatch...\n", "\n", "fn main() {\n", " let x = 5u8;\n", " let y = \"Hello\".to_string();\n", "\n", " static_dispatch(x);\n", " dynamic_dispatch(&y);\n", "\n", " println!(\"Success!\");\n", "}\n", "\n", "main();" ] } ], "metadata": { "kernelspec": { "display_name": "Rust", "language": "rust", "name": "rust" }, "language_info": { "codemirror_mode": "rust", "file_extension": ".rs", "mimetype": "text/rust", "name": "Rust", "pygment_lexer": "rust", "version": "" } }, "nbformat": 4, "nbformat_minor": 2 }