Skip to content

Commit

Permalink
rustlings: 强大的迭代器,返回值类型导致迭代器不同,同样的代码就能有不一样的行为
Browse files Browse the repository at this point in the history
  • Loading branch information
davidxifeng committed Aug 6, 2022
1 parent 7b2d6ed commit b052ce9
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 28 deletions.
64 changes: 64 additions & 0 deletions .archive/sys/csapp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <stdio.h>
// 使用-Og 选项编译

// mult2:
// movq %rdi, %rax
// imulq %rsi, %rax
// ret
long mult2(long a, long b) {
long s = a * b;
return s;
}

/*
mult_store:
pushq %rbx
movq %rdx, %rbx
call mult2
movq %rax, (%rbx)
popq %rbx
ret
*/
void mult_store(long x, long y, long *dest) {
// 开启O3优化的情况下,下面的调用会直接内联.
long t = mult2(x, y);
*dest = t;
}

//globalv:
// .quad 2
long int globalv = 2;


// 栈寄存器-24, 分配栈空间
int main(int argc, char **argv) {
long d; // 8(%rsp)
//
mult_store(2, 3, &d); // leq指令加载有效地址,保存到rdx,第三个参数寄存器
// 然后是两个立即数mov到第二 第一个参数寄存器
// call
// 先设置第二个参数rsi,然后是第一个参数edi
printf("2 * 3 -> %ld\n", d);

return 0;
}

/*
.LC0:
.string "2 * 3 -> %ld\n"
main:
subq $24, %rsp
leaq 8(%rsp), %rdx
movl $3, %esi
movl $2, %edi
call mult_store
movq 8(%rsp), %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
addq $24, %rsp
ret
*/
2 changes: 0 additions & 2 deletions rust/rustlings/exercises/lifetimes/lifetimes1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
//
// Execute `rustlings hint lifetimes1` 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() {
x
Expand Down
4 changes: 1 addition & 3 deletions rust/rustlings/exercises/lifetimes/lifetimes2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +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() {
x
Expand All @@ -19,8 +17,8 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
{
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is {}", result);
Expand Down
8 changes: 3 additions & 5 deletions rust/rustlings/exercises/lifetimes/lifetimes3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
//
// 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() {
Expand Down
10 changes: 4 additions & 6 deletions rust/rustlings/exercises/standard_library_types/iterators1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@
//
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a hint.

// I AM NOT DONE

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
}
25 changes: 20 additions & 5 deletions rust/rustlings/exercises/standard_library_types/iterators2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
// can offer. Follow the steps to complete the exercise.
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a hint.

// I AM NOT DONE

// Step 1.
// Complete the `capitalize_first` function.
// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
None => String::new(),
Some(first) => ???,
Some(first) => {
let mut s = String::new();
s.push(first.to_ascii_uppercase());
s.push_str(&c.as_str());
s
}
}
}

Expand All @@ -21,15 +24,26 @@ 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![]
let mut r = vec![];

for word in words.iter() {
r.push(capitalize_first(&word));
}

r
}

// Step 3.
// Apply the `capitalize_first` function again to a slice of string slices.
// Return a single string.
// ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String {
String::new()
let mut r = String::new();
for word in words.iter() {
r += &capitalize_first(&word);
}

r
}

#[cfg(test)]
Expand All @@ -39,6 +53,7 @@ mod tests {
#[test]
fn test_success() {
assert_eq!(capitalize_first("hello"), "Hello");
assert_eq!(capitalize_first("h"), "H");
}

#[test]
Expand Down
35 changes: 28 additions & 7 deletions rust/rustlings/exercises/standard_library_types/iterators3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,42 @@ 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!();
match b {
0 => Err(DivisionError::DivideByZero),
_ => {
if a % b == 0 {
Ok(a / b)
} else {
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() -> () {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
fn result_with_list() -> Result<Vec<i32>, DivisionError> {
vec![27, 297, 38502, 81]
.into_iter()
.map(|n| divide(n, 27))
.collect()
}

// 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() -> () {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
fn list_of_results() -> Vec<Result<i32, DivisionError>> {
// 删掉一些变量后改成了一个表达式
// rust迭代器确实强悍,完全一样的代码,就因为返回类型不同,所以
// 迭代方式也不同,对错误的处理也就不同,执行过程也不一样了
// 这个版本,遇到错误后还会执行下一个,直到整个vec迭代完成
// 上个版本,遇到错误后就停止迭代了,成功才会迭代完整个vec
vec![27, 297, 38502, 81]
.into_iter()
.map(|n| divide(n, 27))
.collect()
}

#[cfg(test)]
Expand Down

0 comments on commit b052ce9

Please sign in to comment.