mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-01-03 17:29:18 +00:00
完成rustlings
This commit is contained in:
parent
5aa0a05c76
commit
ed0b581e04
@ -6,9 +6,8 @@
|
||||
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn main() {
|
||||
let mut shopping_list: Vec<?> = Vec::new();
|
||||
let mut shopping_list: Vec<&str> = Vec::new();
|
||||
shopping_list.push("milk");
|
||||
}
|
||||
|
||||
@ -6,14 +6,13 @@
|
||||
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
struct Wrapper {
|
||||
value: u32,
|
||||
struct Wrapper<T> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl Wrapper {
|
||||
pub fn new(value: u32) -> Self {
|
||||
impl<T> Wrapper<T> {
|
||||
pub fn new(value: T) -> Self {
|
||||
Wrapper { value }
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
trait AppendBar {
|
||||
fn append_bar(self) -> Self;
|
||||
@ -15,6 +15,9 @@ trait AppendBar {
|
||||
|
||||
impl AppendBar for String {
|
||||
// TODO: Implement `AppendBar` for type `String`.
|
||||
fn append_bar(self)->Self{
|
||||
format!("{}Bar",self)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -8,11 +8,16 @@
|
||||
//
|
||||
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
trait AppendBar {
|
||||
fn append_bar(self) -> Self;
|
||||
}
|
||||
impl AppendBar for Vec<String> {
|
||||
fn append_bar(mut self)->Self{
|
||||
self.push("Bar".to_string());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement trait `AppendBar` for a vector of strings.
|
||||
|
||||
|
||||
@ -8,10 +8,11 @@
|
||||
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
pub trait Licensed {
|
||||
fn licensing_info(&self) -> String;
|
||||
fn licensing_info(&self) -> String{
|
||||
"Some information".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
struct SomeSoftware {
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
pub trait Licensed {
|
||||
fn licensing_info(&self) -> String {
|
||||
@ -23,7 +23,7 @@ impl Licensed for SomeSoftware {}
|
||||
impl Licensed for OtherSoftware {}
|
||||
|
||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||
fn compare_license_types(software: ??, software_two: ??) -> bool {
|
||||
fn compare_license_types(software: impl Licensed, software_two:impl Licensed) -> bool {
|
||||
software.licensing_info() == software_two.licensing_info()
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
pub trait SomeTrait {
|
||||
fn some_function(&self) -> bool {
|
||||
@ -30,7 +29,7 @@ impl SomeTrait for OtherStruct {}
|
||||
impl OtherTrait for OtherStruct {}
|
||||
|
||||
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||
fn some_func(item: ??) -> bool {
|
||||
fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
|
||||
item.some_function() && item.other_function()
|
||||
}
|
||||
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn longest(x: &str, y: &str) -> &str {
|
||||
|
||||
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||
if x.len() > y.len() {
|
||||
x
|
||||
} else {
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||
if x.len() > y.len() {
|
||||
@ -22,6 +21,8 @@ fn main() {
|
||||
{
|
||||
let string2 = String::from("xyz");
|
||||
result = longest(string1.as_str(), string2.as_str());
|
||||
//移动打印行
|
||||
println!("The longest string is '{}'", result);
|
||||
}
|
||||
println!("The longest string is '{}'", result);
|
||||
|
||||
}
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
struct Book {
|
||||
author: &str,
|
||||
title: &str,
|
||||
|
||||
struct Book<'a> {
|
||||
author: &'a str,
|
||||
title: &'a str,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -10,12 +10,13 @@
|
||||
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn you_can_assert() {
|
||||
assert!();
|
||||
// assert!(false);
|
||||
assert!(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,12 +6,14 @@
|
||||
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn you_can_assert_eq() {
|
||||
assert_eq!();
|
||||
// assert_eq!(true,false);
|
||||
assert_eq!(true,true);
|
||||
assert_eq!("a","a");
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
pub fn is_even(num: i32) -> bool {
|
||||
num % 2 == 0
|
||||
@ -19,11 +19,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn is_true_when_even() {
|
||||
assert!();
|
||||
assert!(is_even(10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_false_when_odd() {
|
||||
assert!();
|
||||
assert!(!is_even(11));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
struct Rectangle {
|
||||
width: i32,
|
||||
@ -30,17 +30,20 @@ mod tests {
|
||||
fn correct_width_and_height() {
|
||||
// This test should check if the rectangle is the size that we pass into its constructor
|
||||
let rect = Rectangle::new(10, 20);
|
||||
assert_eq!(???, 10); // check width
|
||||
assert_eq!(???, 20); // check height
|
||||
assert_eq!(rect.width, 10); // check width
|
||||
assert_eq!(rect.height, 20); // check height
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn negative_width() {
|
||||
// This test should check if program panics when we try to create rectangle with negative width
|
||||
let _rect = Rectangle::new(-10, 10);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn negative_height() {
|
||||
// This test should check if program panics when we try to create rectangle with negative height
|
||||
let _rect = Rectangle::new(10, -10);
|
||||
|
||||
@ -9,18 +9,17 @@
|
||||
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#[test]
|
||||
fn main() {
|
||||
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
||||
|
||||
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
|
||||
let mut my_iterable_fav_fruits = my_fav_fruits.iter(); // TODO: Step 1
|
||||
|
||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
|
||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
|
||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"custard apple")); // TODO: Step 2
|
||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
|
||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
|
||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"peach")); // TODO: Step 3
|
||||
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
|
||||
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
|
||||
assert_eq!(my_iterable_fav_fruits.next(), None); // TODO: Step 4
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
// Step 1.
|
||||
// Complete the `capitalize_first` function.
|
||||
@ -15,7 +15,7 @@ pub fn capitalize_first(input: &str) -> String {
|
||||
let mut c = input.chars();
|
||||
match c.next() {
|
||||
None => String::new(),
|
||||
Some(first) => ???,
|
||||
Some(first) => first.to_uppercase().collect::<String>()+c.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,8 @@ pub fn capitalize_first(input: &str) -> String {
|
||||
// Return a vector of strings.
|
||||
// ["hello", "world"] -> ["Hello", "World"]
|
||||
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
||||
vec![]
|
||||
words.iter().map(|v|{capitalize_first(v)}).collect::<Vec<String>>()
|
||||
|
||||
}
|
||||
|
||||
// Step 3.
|
||||
@ -32,7 +33,11 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
||||
// Return a single string.
|
||||
// ["hello", " ", "world"] -> "Hello World"
|
||||
pub fn capitalize_words_string(words: &[&str]) -> String {
|
||||
String::new()
|
||||
|
||||
words.iter()
|
||||
.map(|&word| capitalize_first(word))
|
||||
.collect::<Vec<String>>()
|
||||
.join("")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum DivisionError {
|
||||
@ -26,23 +25,37 @@ pub struct NotDivisibleError {
|
||||
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
|
||||
// Otherwise, return a suitable error.
|
||||
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
|
||||
todo!();
|
||||
// todo!()
|
||||
if b ==0 {
|
||||
return Err(DivisionError::DivideByZero)
|
||||
}
|
||||
if a%b == 0{
|
||||
return Ok(a/b)
|
||||
}else{
|
||||
return Err(DivisionError::NotDivisible(NotDivisibleError{ dividend: a,divisor: b}))
|
||||
}
|
||||
}
|
||||
|
||||
// Complete the function and return a value of the correct type so the test
|
||||
// passes.
|
||||
// Desired output: Ok([1, 11, 1426, 3])
|
||||
fn result_with_list() -> () {
|
||||
fn result_with_list() -> Result<Vec<i32>, DivisionError>{
|
||||
let numbers = vec![27, 297, 38502, 81];
|
||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||
let division_results: Result<Vec<i32>, DivisionError> = numbers.into_iter()
|
||||
.map(|n| divide(n, 27))
|
||||
.collect();
|
||||
division_results
|
||||
}
|
||||
|
||||
// Complete the function and return a value of the correct type so the test
|
||||
// passes.
|
||||
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
|
||||
fn list_of_results() -> () {
|
||||
fn list_of_results() -> Vec<Result<i32, DivisionError>> {
|
||||
let numbers = vec![27, 297, 38502, 81];
|
||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||
let division_results: Vec<Result<i32, DivisionError>> = numbers.into_iter()
|
||||
.map(|n| divide(n, 27))
|
||||
.collect();
|
||||
division_results
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -3,9 +3,11 @@
|
||||
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
pub fn factorial(num: u64) -> u64 {
|
||||
// (1..=num).fold(1,|acc,x|acc*x)
|
||||
(1..=num).product()
|
||||
// Complete this function to return the factorial of num
|
||||
// Do not use:
|
||||
// - return
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@ -35,7 +34,7 @@ fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||
// map is a hashmap with String keys and Progress values.
|
||||
// map = { "variables1": Complete, "from_str": None, ... }
|
||||
todo!();
|
||||
map.values().filter(|&val|val == & value).count()
|
||||
}
|
||||
|
||||
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
||||
@ -54,7 +53,10 @@ fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Pr
|
||||
// collection is a slice of hashmaps.
|
||||
// collection = [{ "variables1": Complete, "from_str": None, ... },
|
||||
// { "variables2": Complete, ... }, ... ]
|
||||
todo!();
|
||||
collection.iter().map(|map|{
|
||||
map.values().filter(|&val|val == & value).count()
|
||||
}).sum()
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
//
|
||||
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
#![forbid(unused_imports)] // Do not change this, (or the next) line.
|
||||
use std::sync::Arc;
|
||||
@ -29,11 +29,11 @@ use std::thread;
|
||||
|
||||
fn main() {
|
||||
let numbers: Vec<_> = (0..100u32).collect();
|
||||
let shared_numbers = // TODO
|
||||
let shared_numbers = Arc::new(numbers); // TODO
|
||||
let mut joinhandles = Vec::new();
|
||||
|
||||
for offset in 0..8 {
|
||||
let child_numbers = // TODO
|
||||
let child_numbers =Arc::clone(&shared_numbers); // TODO
|
||||
joinhandles.push(thread::spawn(move || {
|
||||
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
|
||||
println!("Sum of offset {} is {}", offset, sum);
|
||||
|
||||
@ -18,11 +18,10 @@
|
||||
//
|
||||
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub enum List {
|
||||
Cons(i32, List),
|
||||
Cons(i32, Box<List>),
|
||||
Nil,
|
||||
}
|
||||
|
||||
@ -35,11 +34,13 @@ fn main() {
|
||||
}
|
||||
|
||||
pub fn create_empty_list() -> List {
|
||||
todo!()
|
||||
List::Nil
|
||||
|
||||
}
|
||||
|
||||
//创建不为空的
|
||||
pub fn create_non_empty_list() -> List {
|
||||
todo!()
|
||||
List::Cons(0,Box::new(List::Nil))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
//
|
||||
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
@ -49,6 +49,8 @@ mod tests {
|
||||
let mut input = Cow::from(&slice[..]);
|
||||
match abs_all(&mut input) {
|
||||
// TODO
|
||||
Cow::Borrowed(_)=>{Ok(())}
|
||||
_ => Err("Expected Borrowed value"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +63,8 @@ mod tests {
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
// TODO
|
||||
Cow::Owned(_) => Ok(()),
|
||||
_ => Err("Expected owned value"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +77,8 @@ mod tests {
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
// TODO
|
||||
Cow::Owned(_) => Ok(()),
|
||||
_ => Err("Expected owned value"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
//
|
||||
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -61,17 +60,17 @@ fn main() {
|
||||
jupiter.details();
|
||||
|
||||
// TODO
|
||||
let saturn = Planet::Saturn(Rc::new(Sun {}));
|
||||
let saturn = Planet::Saturn(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
|
||||
saturn.details();
|
||||
|
||||
// TODO
|
||||
let uranus = Planet::Uranus(Rc::new(Sun {}));
|
||||
let uranus = Planet::Uranus(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
|
||||
uranus.details();
|
||||
|
||||
// TODO
|
||||
let neptune = Planet::Neptune(Rc::new(Sun {}));
|
||||
let neptune = Planet::Neptune(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
|
||||
neptune.details();
|
||||
|
||||
@ -91,13 +90,13 @@ fn main() {
|
||||
|
||||
drop(mars);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
|
||||
|
||||
drop(earth);
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
|
||||
|
||||
drop(venus);
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
|
||||
|
||||
drop(mercury);
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
@ -27,6 +26,7 @@ fn main() {
|
||||
let mut results: Vec<u128> = vec![];
|
||||
for handle in handles {
|
||||
// TODO: a struct is returned from thread::spawn, can you use it?
|
||||
results.push(handle.join().unwrap())
|
||||
}
|
||||
|
||||
if results.len() != 10 {
|
||||
|
||||
@ -7,25 +7,26 @@
|
||||
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::sync::Mutex;
|
||||
|
||||
struct JobStatus {
|
||||
jobs_completed: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let status = Arc::new(JobStatus { jobs_completed: 0 });
|
||||
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
|
||||
let mut handles = vec![];
|
||||
for _ in 0..10 {
|
||||
let status_shared = Arc::clone(&status);
|
||||
let handle = thread::spawn(move || {
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
// TODO: You must take an action before you update a shared value
|
||||
status_shared.jobs_completed += 1;
|
||||
let mut status_shared_mut= status_shared.lock().unwrap();
|
||||
status_shared_mut.jobs_completed += 1;
|
||||
});
|
||||
handles.push(handle);
|
||||
}
|
||||
@ -34,6 +35,7 @@ fn main() {
|
||||
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice
|
||||
// anything interesting in the output? Do you have to 'join' on all the
|
||||
// handles?
|
||||
println!("jobs completed {}", ???);
|
||||
let status = status.lock().unwrap();
|
||||
println!("jobs completed {}", status.jobs_completed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
use std::sync::mpsc;
|
||||
use std::sync::Arc;
|
||||
@ -31,10 +31,12 @@ fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
|
||||
let qc1 = Arc::clone(&qc);
|
||||
let qc2 = Arc::clone(&qc);
|
||||
|
||||
//这里克隆一下,避免使用所有权转移
|
||||
let tx_cloned = tx.clone();
|
||||
thread::spawn(move || {
|
||||
for val in &qc1.first_half {
|
||||
println!("sending {:?}", val);
|
||||
tx.send(*val).unwrap();
|
||||
tx_cloned.send(*val).unwrap();
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
@ -12,5 +11,5 @@ macro_rules! my_macro {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
my_macro();
|
||||
my_macro!();
|
||||
}
|
||||
|
||||
@ -3,12 +3,14 @@
|
||||
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
fn main() {
|
||||
my_macro!();
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
println!("Check out my macro!");
|
||||
|
||||
@ -5,9 +5,10 @@
|
||||
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
mod macros {
|
||||
#[macro_export] //导出定义的宏
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
println!("Check out my macro!");
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
#[rustfmt::skip]
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
println!("Check out my macro!");
|
||||
}
|
||||
};
|
||||
($val:expr) => {
|
||||
println!("Look at this other macro: {}", $val);
|
||||
}
|
||||
|
||||
7
exercises/22_clippy/Cargo.lock
generated
Normal file
7
exercises/22_clippy/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "clippy3"
|
||||
version = "0.0.1"
|
||||
7
exercises/22_clippy/Cargo.toml
Normal file
7
exercises/22_clippy/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "clippy3"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
[[bin]]
|
||||
name = "clippy3"
|
||||
path = "clippy3.rs"
|
||||
@ -9,12 +9,13 @@
|
||||
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
use std::f32;
|
||||
|
||||
|
||||
fn main() {
|
||||
let pi = 3.14f32;
|
||||
let pi = std::f32::consts::PI;
|
||||
let radius = 5.00f32;
|
||||
|
||||
let area = pi * f32::powi(radius, 2);
|
||||
|
||||
@ -3,12 +3,10 @@
|
||||
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn main() {
|
||||
let mut res = 42;
|
||||
let option = Some(12);
|
||||
for x in option {
|
||||
while let Some(x) = option{
|
||||
res += x;
|
||||
}
|
||||
println!("{}", res);
|
||||
|
||||
@ -3,28 +3,31 @@
|
||||
// Here's a couple more easy Clippy fixes, so you can see its utility.
|
||||
// No hints.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#[allow(unused_variables, unused_assignments)]
|
||||
fn main() {
|
||||
let my_option: Option<()> = None;
|
||||
if my_option.is_none() {
|
||||
my_option.unwrap();
|
||||
}
|
||||
// if my_option.is_none() {
|
||||
// my_option.unwrap(); //这里怎么解决
|
||||
// }
|
||||
|
||||
let my_arr = &[
|
||||
-1, -2, -3
|
||||
-1, -2, -3,
|
||||
-4, -5, -6
|
||||
];
|
||||
println!("My array! Here it is: {:?}", my_arr);
|
||||
|
||||
let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
|
||||
// let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
|
||||
let mut my_empty_vec = vec![1, 2, 3, 4, 5];
|
||||
my_empty_vec.clear();
|
||||
|
||||
println!("This Vec is empty, see? {:?}", my_empty_vec);
|
||||
|
||||
let mut value_a = 45;
|
||||
let mut value_b = 66;
|
||||
// Let's swap these two!
|
||||
value_a = value_b;
|
||||
value_b = value_a;
|
||||
// value_a = value_b;
|
||||
// value_b = value_a;
|
||||
std::mem::swap(&mut value_a, &mut value_b);
|
||||
println!("value a: {}; value b: {}", value_a, value_b);
|
||||
}
|
||||
|
||||
@ -7,25 +7,33 @@
|
||||
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
// Obtain the number of bytes (not characters) in the given argument.
|
||||
// TODO: Add the AsRef trait appropriately as a trait bound.
|
||||
fn byte_counter<T>(arg: T) -> usize {
|
||||
fn byte_counter<T>(arg: T) -> usize
|
||||
where T:AsRef<str>
|
||||
{
|
||||
arg.as_ref().as_bytes().len()
|
||||
}
|
||||
|
||||
// Obtain the number of characters (not bytes) in the given argument.
|
||||
// TODO: Add the AsRef trait appropriately as a trait bound.
|
||||
fn char_counter<T>(arg: T) -> usize {
|
||||
fn char_counter<T>(arg: T) -> usize
|
||||
where T:AsRef<str>
|
||||
{
|
||||
arg.as_ref().chars().count()
|
||||
}
|
||||
|
||||
//TODO 这里后续看看怎么有其他的方式进行修改
|
||||
// Squares a number using as_mut().
|
||||
// TODO: Add the appropriate trait bound.
|
||||
fn num_sq<T>(arg: &mut T) {
|
||||
fn num_sq<T>(arg: &mut T)
|
||||
where T:AsMut<u32>
|
||||
{
|
||||
// TODO: Implement the function body.
|
||||
???
|
||||
let slice = arg.as_mut();
|
||||
*slice = *slice * *slice
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -40,10 +40,36 @@ impl Default for Person {
|
||||
// If while parsing the age, something goes wrong, then return the default of
|
||||
// Person Otherwise, then return an instantiated Person object with the results
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
impl From<&str> for Person {
|
||||
fn from(s: &str) -> Person {
|
||||
if s.len() == 0 {
|
||||
return Person::default();
|
||||
}
|
||||
let s_vec = s.split(",").collect::<Vec<&str>>();
|
||||
if s_vec.len() <2{
|
||||
return Person::default();
|
||||
}
|
||||
let mut persion = Person::default();
|
||||
let name = s_vec[0].to_string();
|
||||
if name.len() == 0 {
|
||||
return Person::default();
|
||||
}
|
||||
let age = s_vec[1];
|
||||
|
||||
if age.len() == 0 {
|
||||
return Person::default();
|
||||
}
|
||||
|
||||
let age = if let Ok(age) = age.parse::<usize>() {
|
||||
age
|
||||
} else {
|
||||
return Person::default();
|
||||
};
|
||||
|
||||
Person {
|
||||
name: name,
|
||||
age: age,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ enum ParsePersonError {
|
||||
ParseInt(ParseIntError),
|
||||
}
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
// Steps:
|
||||
// 1. If the length of the provided string is 0, an error should be returned
|
||||
@ -49,12 +48,64 @@ enum ParsePersonError {
|
||||
// you want to return a string error message, you can do so via just using
|
||||
// return `Err("my error message".into())`.
|
||||
|
||||
//没有使用索引获取的
|
||||
// impl FromStr for Person {
|
||||
// type Err = ParsePersonError;
|
||||
// fn from_str(s: &str) -> Result<Person, Self::Err> {
|
||||
// if s.is_empty(){
|
||||
// return Err(ParsePersonError::Empty);
|
||||
// }
|
||||
// let mut parts = s.split(",");
|
||||
// if parts.clone().count() !=2{
|
||||
// return Err(ParsePersonError::BadLen);
|
||||
// }
|
||||
// let name= parts.next().unwrap_or("").to_string();
|
||||
// let age = parts.next().unwrap_or("").to_string();
|
||||
// if name.is_empty() {
|
||||
// return Err(ParsePersonError::NoName);
|
||||
// }
|
||||
// let age = match age.parse::<usize>(){
|
||||
// Ok(age) =>age,
|
||||
// Err(e) =>return Err(ParsePersonError::ParseInt(e))
|
||||
// };
|
||||
// Ok(Person{
|
||||
// name,
|
||||
// age
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
impl FromStr for Person {
|
||||
type Err = ParsePersonError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
||||
if s.is_empty() {
|
||||
return Err(ParsePersonError::Empty);
|
||||
}
|
||||
|
||||
let parts: Vec<&str> = s.split(',').collect();
|
||||
|
||||
if parts.len() != 2 {
|
||||
return Err(ParsePersonError::BadLen);
|
||||
}
|
||||
|
||||
let name = parts[0].to_string();
|
||||
if name.is_empty() {
|
||||
return Err(ParsePersonError::NoName);
|
||||
}
|
||||
|
||||
let age = match parts[1].parse::<usize>() {
|
||||
Ok(age) => age,
|
||||
Err(e) => return Err(ParsePersonError::ParseInt(e)),
|
||||
};
|
||||
|
||||
Ok(Person { name, age })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
let p = "Mark,20".parse::<Person>().unwrap();
|
||||
println!("{:?}", p);
|
||||
|
||||
@ -27,7 +27,7 @@ enum IntoColorError {
|
||||
IntConversion,
|
||||
}
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
|
||||
// Your task is to complete this implementation and return an Ok result of inner
|
||||
// type Color. You need to create an implementation for a tuple of three
|
||||
@ -40,7 +40,26 @@ enum IntoColorError {
|
||||
// Tuple implementation
|
||||
impl TryFrom<(i16, i16, i16)> for Color {
|
||||
type Error = IntoColorError;
|
||||
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
|
||||
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error>
|
||||
{
|
||||
let (red,green,blue) = tuple;
|
||||
if red <0 ||red>255{
|
||||
return Err(IntoColorError::IntConversion)
|
||||
}
|
||||
if green <0 ||green>255{
|
||||
return Err(IntoColorError::IntConversion)
|
||||
}
|
||||
|
||||
if blue <0 ||blue>255{
|
||||
return Err(IntoColorError::IntConversion)
|
||||
}
|
||||
|
||||
|
||||
Ok(Color{
|
||||
red:red as u8,
|
||||
green: green as u8,
|
||||
blue:blue as u8,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +67,19 @@ impl TryFrom<(i16, i16, i16)> for Color {
|
||||
impl TryFrom<[i16; 3]> for Color {
|
||||
type Error = IntoColorError;
|
||||
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
|
||||
|
||||
for &value in &arr {
|
||||
if value < 0 || value > 255 {
|
||||
return Err(IntoColorError::IntConversion);
|
||||
}
|
||||
}
|
||||
let arr = arr.iter().map(|f|*f as u8).collect::<Vec<u8>>();
|
||||
|
||||
Ok(Color{
|
||||
red:arr[0],
|
||||
green:arr[1],
|
||||
blue:arr[2],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +87,20 @@ impl TryFrom<[i16; 3]> for Color {
|
||||
impl TryFrom<&[i16]> for Color {
|
||||
type Error = IntoColorError;
|
||||
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
|
||||
if slice.len() ==3{
|
||||
for &value in slice {
|
||||
if value < 0 || value > 255 {
|
||||
return Err(IntoColorError::IntConversion);
|
||||
}
|
||||
}
|
||||
Ok(Color{
|
||||
red:slice[0] as u8,
|
||||
green:slice[1] as u8,
|
||||
blue:slice[2] as u8,
|
||||
})
|
||||
}else{
|
||||
return Err(IntoColorError::BadLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,11 +10,10 @@
|
||||
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a
|
||||
// hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn average(values: &[f64]) -> f64 {
|
||||
let total = values.iter().sum::<f64>();
|
||||
total / values.len()
|
||||
total / values.len() as f64
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -16,15 +16,14 @@
|
||||
//
|
||||
// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
pub struct ReportCard {
|
||||
pub grade: f32,
|
||||
pub struct ReportCard<T> {
|
||||
pub grade: T,
|
||||
pub student_name: String,
|
||||
pub student_age: u8,
|
||||
}
|
||||
|
||||
impl ReportCard {
|
||||
impl<T:std::fmt::Display> ReportCard<T> {
|
||||
pub fn print(&self) -> String {
|
||||
format!("{} ({}) - achieved a grade of {}",
|
||||
&self.student_name, &self.student_age, &self.grade)
|
||||
@ -52,7 +51,7 @@ mod tests {
|
||||
fn generate_alphabetic_report_card() {
|
||||
// TODO: Make sure to change the grade here after you finish the exercise.
|
||||
let report_card = ReportCard {
|
||||
grade: 2.1,
|
||||
grade:"A+",
|
||||
student_name: "Gary Plotter".to_string(),
|
||||
student_age: 11,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user