initial commit
This commit is contained in:
19
traits/README.md
Normal file
19
traits/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Traits
|
||||
|
||||
A trait is a collection of methods.
|
||||
|
||||
Data types can implement traits. To do so, the methods making up the trait are defined for the data type. For example, the `String` data type implements the `From<&str>` trait. This allows a user to write `String::from("hello")`.
|
||||
|
||||
In this way, traits are somewhat similar to Java interfaces and C++ abstract classes.
|
||||
|
||||
Some additional common Rust traits include:
|
||||
|
||||
- `Clone` (the `clone` method)
|
||||
- `Display` (which allows formatted display via `{}`)
|
||||
- `Debug` (which allows formatted display via `{:?}`)
|
||||
|
||||
Because traits indicate shared behavior between data types, they are useful when writing generics.
|
||||
|
||||
## Further information
|
||||
|
||||
- [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
|
45
traits/traits1.rs
Normal file
45
traits/traits1.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
// traits1.rs
|
||||
//
|
||||
// Time to implement some traits! Your task is to implement the trait
|
||||
// `AppendBar` for the type `String`. The trait AppendBar has only one function,
|
||||
// which appends "Bar" to any object implementing this trait.
|
||||
//
|
||||
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM DONE
|
||||
|
||||
trait AppendBar {
|
||||
fn append_bar(self) -> Self;
|
||||
}
|
||||
|
||||
impl AppendBar for String {
|
||||
// TODO: Implement `AppendBar` for type `String`.
|
||||
fn append_bar(self) -> Self {
|
||||
self + "Bar"
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = String::from("Foo");
|
||||
let s = s.append_bar();
|
||||
println!("s: {}", s);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn is_foo_bar() {
|
||||
assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_bar_bar() {
|
||||
assert_eq!(
|
||||
String::from("").append_bar().append_bar(),
|
||||
String::from("BarBar")
|
||||
);
|
||||
}
|
||||
}
|
35
traits/traits2.rs
Normal file
35
traits/traits2.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
// traits2.rs
|
||||
//
|
||||
// Your task is to implement the trait `AppendBar` for a vector of strings. To
|
||||
// implement this trait, consider for a moment what it means to 'append "Bar"'
|
||||
// to a vector of strings.
|
||||
//
|
||||
// No boiler plate code this time, you can do this!
|
||||
//
|
||||
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM DONE
|
||||
|
||||
trait AppendBar {
|
||||
fn append_bar(self) -> Self;
|
||||
}
|
||||
|
||||
// TODO: Implement trait `AppendBar` for a vector of strings.
|
||||
impl AppendBar for Vec<String> {
|
||||
fn append_bar(mut self) -> Self {
|
||||
self.push(String::from("Bar"));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn is_vec_pop_eq_bar() {
|
||||
let mut foo = vec![String::from("Foo")].append_bar();
|
||||
assert_eq!(foo.pop().unwrap(), String::from("Bar"));
|
||||
assert_eq!(foo.pop().unwrap(), String::from("Foo"));
|
||||
}
|
||||
}
|
44
traits/traits3.rs
Normal file
44
traits/traits3.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
// traits3.rs
|
||||
//
|
||||
// Your task is to implement the Licensed trait for both structures and have
|
||||
// them return the same information without writing the same function twice.
|
||||
//
|
||||
// Consider what you can add to the Licensed trait.
|
||||
//
|
||||
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM DONE
|
||||
|
||||
pub trait Licensed {
|
||||
fn licensing_info(&self) -> String {
|
||||
"Some information".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
struct SomeSoftware {
|
||||
version_number: i32,
|
||||
}
|
||||
|
||||
struct OtherSoftware {
|
||||
version_number: String,
|
||||
}
|
||||
|
||||
impl Licensed for SomeSoftware {} // Don't edit this line
|
||||
impl Licensed for OtherSoftware {} // Don't edit this line
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn is_licensing_info_the_same() {
|
||||
let licensing_info = String::from("Some information");
|
||||
let some_software = SomeSoftware { version_number: 1 };
|
||||
let other_software = OtherSoftware {
|
||||
version_number: "v2.0.0".to_string(),
|
||||
};
|
||||
assert_eq!(some_software.licensing_info(), licensing_info);
|
||||
assert_eq!(other_software.licensing_info(), licensing_info);
|
||||
}
|
||||
}
|
49
traits/traits4.rs
Normal file
49
traits/traits4.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
// traits4.rs
|
||||
//
|
||||
// Your task is to replace the '??' sections so the code compiles.
|
||||
//
|
||||
// Don't change any line other than the marked one.
|
||||
//
|
||||
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM DONE
|
||||
|
||||
pub trait Licensed {
|
||||
fn licensing_info(&self) -> String {
|
||||
"some information".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
struct SomeSoftware {}
|
||||
|
||||
struct OtherSoftware {}
|
||||
|
||||
impl Licensed for SomeSoftware {}
|
||||
impl Licensed for OtherSoftware {}
|
||||
|
||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||
fn compare_license_types(software: impl Licensed, software_two: impl Licensed) -> bool {
|
||||
software.licensing_info() == software_two.licensing_info()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn compare_license_information() {
|
||||
let some_software = SomeSoftware {};
|
||||
let other_software = OtherSoftware {};
|
||||
|
||||
assert!(compare_license_types(some_software, other_software));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compare_license_information_backwards() {
|
||||
let some_software = SomeSoftware {};
|
||||
let other_software = OtherSoftware {};
|
||||
|
||||
assert!(compare_license_types(other_software, some_software));
|
||||
}
|
||||
}
|
40
traits/traits5.rs
Normal file
40
traits/traits5.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
// traits5.rs
|
||||
//
|
||||
// Your task is to replace the '??' sections so the code compiles.
|
||||
//
|
||||
// Don't change any line other than the marked one.
|
||||
//
|
||||
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM DONE
|
||||
|
||||
pub trait SomeTrait {
|
||||
fn some_function(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OtherTrait {
|
||||
fn other_function(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct SomeStruct {}
|
||||
struct OtherStruct {}
|
||||
|
||||
impl SomeTrait for SomeStruct {}
|
||||
impl OtherTrait for SomeStruct {}
|
||||
impl SomeTrait for OtherStruct {}
|
||||
impl OtherTrait for OtherStruct {}
|
||||
|
||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||
fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
|
||||
item.some_function() && item.other_function()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
some_func(SomeStruct {});
|
||||
some_func(OtherStruct {});
|
||||
}
|
Reference in New Issue
Block a user