提交 410cacbe 编写于 作者: 梦境迷离's avatar 梦境迷离 提交者: 梦境迷离

refactor

上级 9ba3b5f4
......@@ -21,11 +21,11 @@ do
echo "############ [ not enable $lang language in this project ]"
break
fi
# compile rust
# compile rust and fmt code
case "$lang" in
"rust")
echo "################# [ compile $sub_module ]"
`cd $sub_module;cargo build >/dev/null 2>&1 ;cd .. `;;
`cd $sub_module;cargo build >/dev/null 2>&1;cargo fmt --all; cd .. `;;
# compile python
"python")
echo "############ [ TODO ]";;
......
......@@ -19,7 +19,6 @@ struct Node<T> {
prev: Link<T>,
}
impl<T> Node<T> {
fn new(elem: T) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Node {
......@@ -32,7 +31,10 @@ impl<T> Node<T> {
impl<T> List<T> {
pub fn new() -> Self {
List { head: None, tail: None }
List {
head: None,
tail: None,
}
}
pub fn push_front(&mut self, elem: T) {
......@@ -116,23 +118,23 @@ impl<T> List<T> {
//获取尾结点的不可变引用
pub fn peek_back(&self) -> Option<Ref<T>> {
self.tail.as_ref().map(|node| {
Ref::map(node.borrow(), |node| &node.elem)
})
self.tail
.as_ref()
.map(|node| Ref::map(node.borrow(), |node| &node.elem))
}
//获取尾结点的可变引用
pub fn peek_back_mut(&mut self) -> Option<RefMut<T>> {
self.tail.as_ref().map(|node| {
RefMut::map(node.borrow_mut(), |node| &mut node.elem)
})
self.tail
.as_ref()
.map(|node| RefMut::map(node.borrow_mut(), |node| &mut node.elem))
}
//获取头结点的可变引用
pub fn peek_front_mut(&mut self) -> Option<RefMut<T>> {
self.head.as_ref().map(|node| {
RefMut::map(node.borrow_mut(), |node| &mut node.elem)
})
self.head
.as_ref()
.map(|node| RefMut::map(node.borrow_mut(), |node| &mut node.elem))
}
//需要所有权的迭代器
......
......@@ -86,4 +86,4 @@ mod test {
assert_eq!(list.pop(), Some(1));
assert_eq!(list.pop(), None);
}
}
\ No newline at end of file
}
pub mod bad_safe_singly_deque;
pub mod bad_singly_stack;
pub mod ok_singly_stack;
pub mod persistent_singly_stack;
pub mod bad_safe_singly_deque;
pub mod unsafe_singly_queue;
pub fn main() {}
\ No newline at end of file
pub fn main() {}
......@@ -36,16 +36,12 @@ impl<T> List<T> {
//获取第一个元素的不可变引用
pub fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|node| {
&node.elem
})
self.head.as_ref().map(|node| &node.elem)
}
//获取第一个元素的可变引用
pub fn peek_mut(&mut self) -> Option<&mut T> {
self.head.as_mut().map(|node| {
&mut node.elem
})
self.head.as_mut().map(|node| &mut node.elem)
}
pub fn into_iter(self) -> IntoIter<T> {
......@@ -53,11 +49,15 @@ impl<T> List<T> {
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: self.head.as_ref().map(|node| &**node) }
Iter {
next: self.head.as_ref().map(|node| &**node),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut { next: self.head.as_mut().map(|node| &mut **node) }
IterMut {
next: self.head.as_mut().map(|node| &mut **node),
}
}
}
......@@ -150,9 +150,7 @@ mod test {
assert_eq!(list.peek(), Some(&3));
assert_eq!(list.peek_mut(), Some(&mut 3));
list.peek_mut().map(|value| {
*value = 42
});
list.peek_mut().map(|value| *value = 42);
assert_eq!(list.peek(), Some(&42));
assert_eq!(list.pop(), Some(42));
......@@ -197,4 +195,4 @@ mod test {
assert_eq!(iter.next(), Some(&mut 2));
assert_eq!(iter.next(), Some(&mut 1));
}
}
\ No newline at end of file
}
......@@ -25,13 +25,15 @@ impl<T> List<T> {
head: Some(Rc::new(Node {
elem,
next: self.head.clone(),
}))
})),
}
}
pub fn tail(&self) -> List<T> {
//and_then 如果self为[`None`],则返回[`None`],否则调用'f'并包装值,返回结果。有些语言称此操作为flatmap。
List { head: self.head.as_ref().and_then(|node| node.next.clone()) }
List {
head: self.head.as_ref().and_then(|node| node.next.clone()),
}
}
pub fn head(&self) -> Option<&T> {
......@@ -39,7 +41,9 @@ impl<T> List<T> {
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: self.head.as_ref().map(|node| &**node) }
Iter {
next: self.head.as_ref().map(|node| &**node),
}
}
}
......@@ -104,4 +108,4 @@ mod test {
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));
}
}
\ No newline at end of file
}
......@@ -17,14 +17,14 @@ struct Node<T> {
impl<T> List<T> {
pub fn new() -> Self {
//创建一个空的可变的原始行指针
List { head: None, tail: ptr::null_mut() }
List {
head: None,
tail: ptr::null_mut(),
}
}
pub fn push(&mut self, elem: T) {
let mut new_tail = Box::new(Node {
elem,
next: None,
});
let mut new_tail = Box::new(Node { elem, next: None });
//强制为原始指针
let raw_tail: *mut _ = &mut *new_tail;
......@@ -54,15 +54,11 @@ impl<T> List<T> {
}
pub fn peek(&self) -> Option<&T> {
self.head.as_ref().map(|node| {
&node.elem
})
self.head.as_ref().map(|node| &node.elem)
}
pub fn peek_mut(&mut self) -> Option<&mut T> {
self.head.as_mut().map(|node| {
&mut node.elem
})
self.head.as_mut().map(|node| &mut node.elem)
}
pub fn into_iter(self) -> IntoIter<T> {
......@@ -70,11 +66,15 @@ impl<T> List<T> {
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: self.head.as_ref().map(|node| &**node) }
Iter {
next: self.head.as_ref().map(|node| &**node),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut { next: self.head.as_mut().map(|node| &mut **node) }
IterMut {
next: self.head.as_mut().map(|node| &mut **node),
}
}
}
......@@ -201,4 +201,4 @@ mod test {
assert_eq!(iter.next(), Some(&mut 3));
assert_eq!(iter.next(), None);
}
}
\ No newline at end of file
}
......@@ -4,7 +4,9 @@
//by value: T
pub fn closures() {
//闭包是lambda,一个表达式可以省略大括号
fn function(i: i32) -> i32 { i + 1 }
fn function(i: i32) -> i32 {
i + 1
}
let closure_annotated = |i: i32| -> i32 { i + 1 };
let closure_inferred = |i| i + 1;
let i = 1;
......@@ -35,10 +37,10 @@ fn capturing() {
let print = || println!("`color`: {}", color);
print();
let _reborrow = &color;//闭包使用的color能被继续借用
print();//直到最后一次使用print
let _reborrow = &color; //闭包使用的color能被继续借用
print(); //直到最后一次使用print
let _color_moved = color;//最后使用`print`后允许移动或重新借用
let _color_moved = color; //最后使用`print`后允许移动或重新借用
let mut count = 0;
let mut inc = || {
count += 1;
......@@ -55,20 +57,26 @@ fn capturing() {
mem::drop(movable);
};
consume();//仅能被使用一次。
consume(); //仅能被使用一次。
}
fn input_parameters() {
//以闭包作为参数并调用它的函数。
fn apply<F>(f: F) where
// The closure takes no input and returns nothing.
F: FnOnce() {//按值捕获
fn apply<F>(f: F)
where
// The closure takes no input and returns nothing.
F: FnOnce(),
{
//按值捕获
// ^ TODO: Try changing this to `Fn` or `FnMut`.
f();
}
// A function which takes a closure and returns an `i32`.
fn apply_to_3<F>(f: F) -> i32 where F: Fn(i32) -> i32 {
fn apply_to_3<F>(f: F) -> i32
where
F: Fn(i32) -> i32,
{
f(3)
}
......@@ -78,11 +86,11 @@ fn input_parameters() {
//从借来的引用创建自己拥有的数据
let mut farewell = "goodbye".to_owned();
let diary = || {
println!("I said {}.", greeting);//捕获引用
farewell.push_str("!!!");//捕获可变引用
println!("I said {}.", greeting); //捕获引用
farewell.push_str("!!!"); //捕获可变引用
println!("Then I screamed {}.", farewell);
println!("Now I can sleep. zzzzz");
mem::drop(farewell);//捕获值
mem::drop(farewell); //捕获值
};
apply(diary);
let double = |x| 2 * x;
......@@ -91,8 +99,10 @@ fn input_parameters() {
fn type_anonymity() {
// `F`必须是泛型的
fn apply<F>(f: F) where
F: FnOnce() {
fn apply<F>(f: F)
where
F: FnOnce(),
{
f();
}
}
......@@ -145,8 +155,8 @@ fn closures_std() {
//any
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
println!("2 in vec1: {}", vec1.iter().any(|&x| x == 2));//不消耗集合,使用引用捕获
println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2));//消耗集合,使用值捕获
println!("2 in vec1: {}", vec1.iter().any(|&x| x == 2)); //不消耗集合,使用引用捕获
println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2)); //消耗集合,使用值捕获
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
println!("2 in array1: {}", array1.iter().any(|&x| x == 2));
......@@ -155,16 +165,19 @@ fn closures_std() {
//find
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
let mut iter = vec1.iter();//&i32
let mut into_iter = vec2.into_iter();//i32
//解构参数
println!("Find 2 in vec1: {:?}", iter.find(|&&x| x == 2));//`&&i32` to `i32`
println!("Find 2 in vec1: {:?}", iter.find(|x| **x == 2));//参数是`&&i32`,使用时解构
println!("Find 2 in vec2: {:?}", into_iter.find(|&x| x == 2));//`&i32` to `i32`
let mut iter = vec1.iter(); //&i32
let mut into_iter = vec2.into_iter(); //i32
//解构参数
println!("Find 2 in vec1: {:?}", iter.find(|&&x| x == 2)); //`&&i32` to `i32`
println!("Find 2 in vec1: {:?}", iter.find(|x| **x == 2)); //参数是`&&i32`,使用时解构
println!("Find 2 in vec2: {:?}", into_iter.find(|&x| x == 2)); //`&i32` to `i32`
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
println!("Find 2 in array1: {:?}", array1.iter().find(|&&x| x == 2));
println!("Find 2 in array2: {:?}", array2.into_iter().find(|&&x| x == 2));
println!(
"Find 2 in array2: {:?}",
array2.into_iter().find(|&&x| x == 2)
);
//position index
let vec = vec![1, 9, 3, 3, 13, 2];
......@@ -185,7 +198,8 @@ fn higher_order_functions() {
println!("Find the sum of all the squared odd numbers under 1000");
let upper = 1000;
let mut acc = 0;
for n in 0.. {//无穷大
for n in 0.. {
//无穷大
let n_squared = n * n;
if n_squared >= upper {
break;
......@@ -195,11 +209,11 @@ fn higher_order_functions() {
}
println!("imperative style: {}", acc);
//函数式风格
let sum_of_squared_odd_numbers: u32 =
(0..).map(|n| n * n)
.take_while(|&n_squared| n_squared < upper)
.filter(|&n_squared| is_odd(n_squared)) // That are odd
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
let sum_of_squared_odd_numbers: u32 = (0..)
.map(|n| n * n)
.take_while(|&n_squared| n_squared < upper)
.filter(|&n_squared| is_odd(n_squared)) // That are odd
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
println!("functional style: {}", sum_of_squared_odd_numbers);
}
......@@ -222,13 +236,16 @@ fn diverging_functions() {
for i in 0..up_to {
let addition: u32 = match i % 2 == 1 {
true => i,
false => continue,//不返还,不违反match
false => continue, //不返还,不违反match
};
acc += addition;
}
acc
}
println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9));
println!(
"Sum of odd numbers up to 9 (excluding): {}",
sum_odd_numbers(9)
);
//println!("{}", foo()) //error This call never returns.
}
\ No newline at end of file
}
///类型之间的转化
pub fn conversion() {
//FROM
let my_str = "hello";
let my_string = String::from(my_str);
......@@ -25,7 +24,6 @@ pub fn conversion() {
let num: Number = int.into();
println!("My number is {:?}", num);
try_conversion();
//转化为整数
......@@ -64,11 +62,10 @@ fn try_conversion() {
let result: Result<EvenNumber, ()> = 5i32.try_into();
assert_eq!(result, Err(()));
//转化为字符串
use std::fmt;
struct Circle {
radius: i32
radius: i32,
}
impl fmt::Display for Circle {
......@@ -86,16 +83,15 @@ fn expression() {
let y = {
let x_squared = x * x;
let x_cube = x_squared * x;
x_cube + x_squared + x//返回这个表达式
x_cube + x_squared + x //返回这个表达式
};
let z = {
// The semicolon suppresses this expression and `()` is assigned to `z`
2 * x;//以分号结尾的返回 ()
2 * x; //以分号结尾的返回 ()
};
println!("x is {:?}", x);
println!("y is {:?}", y);
println!("z is {:?}", z);
}
......@@ -53,11 +53,17 @@ fn structures() {
println!("second point: ({}, {})", bottom_right.x, bottom_right.y);
//使用“let”绑定对点进行解构
let Point { x: top_edge, y: left_edge } = point;
let Point {
x: top_edge,
y: left_edge,
} = point;
let _rectangle = Rectangle {
//结构体实例也是一个表达式
top_left: Point { x: left_edge, y: top_edge },
top_left: Point {
x: left_edge,
y: top_edge,
},
bottom_right: bottom_right,
};
......@@ -115,7 +121,6 @@ fn enums() {
inspect(load);
inspect(unload);
///类型别名
enum VeryVerboseEnumOfThingsToDoWithNumbers {
Add,
......@@ -137,7 +142,6 @@ fn enums() {
}
}
enum Status {
Rich,
Poor,
......@@ -163,7 +167,6 @@ fn enums() {
Soldier => println!("Soldiers fight!"),
}
///经典的类c结构体
enum Number {
Zero,
......@@ -213,7 +216,7 @@ fn testcase_linkedlist() {
match *self {
//不能拥有尾,因为“self”是借来的;相反,要引用尾
Cons(_, ref tail) => 1 + tail.len(),
Nil => 0
Nil => 0,
}
}
......@@ -224,9 +227,7 @@ fn testcase_linkedlist() {
//返回堆分配的字符串,而不是打印到控制台
format!("{}, {}", head, tail.stringify())
}
Nil => {
format!("Nil")
}
Nil => format!("Nil"),
}
}
}
......@@ -238,7 +239,7 @@ fn testcase_linkedlist() {
list = list.prepend(3);
println!("linked list has length: {}", list.len());
println!("{}", list.stringify());//3, 2, 1, Nil
println!("{}", list.stringify()); //3, 2, 1, Nil
}
pub fn constants() {
......@@ -262,4 +263,4 @@ pub fn constants() {
// Error! Cannot modify a `const`.
//THRESHOLD = 5;
// FIXME ^ Comment out this line
}
\ No newline at end of file
}
......@@ -31,7 +31,7 @@ fn if_else() {
} else {
println!(", and is a big number, halve the number");
n / 2
};//别忘了在这里加分号!所有“let”绑定都需要它
}; //别忘了在这里加分号!所有“let”绑定都需要它
println!("{} -> {}", n, big_n);
}
......@@ -61,12 +61,11 @@ fn loop_while() {
println!("Entered the inner loop");
break 'outer;
}
println!("This point will never be reached");//永远不会被执行,到break 'outer;就会直接退出外层循环
println!("This point will never be reached"); //永远不会被执行,到break 'outer;就会直接退出外层循环
}
println!("Exited the outer loop");
//从loop返回值
let mut counter = 0;
......@@ -99,7 +98,8 @@ fn loop_while() {
fn for_range() {
//`n` = 1, 2, ..., 100
for n in 1..101 {//包含左,不含右,Scala的until不包含右界,to包含右界
for n in 1..101 {
//包含左,不含右,Scala的until不包含右界,to包含右界
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
......@@ -112,7 +112,8 @@ fn for_range() {
}
//`n` = 1, 2, ..., 100
for n in 1..=100 {//包含右界
for n in 1..=100 {
//包含右界
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
......@@ -126,7 +127,8 @@ fn for_range() {
///迭代器
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter() {//将在每次迭代中借用集合的每个元素。因此,在循环之后,该集合将保持不变并可供重用。
for name in names.iter() {
//将在每次迭代中借用集合的每个元素。因此,在循环之后,该集合将保持不变并可供重用。
match name {
&"Ferris" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
......@@ -134,7 +136,8 @@ fn for_range() {
}
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.into_iter() {//消耗集合,以便在每次迭代时提供准确的数据。一旦使用完了集合,就不再可以重复使用,因为它已在循环中“移动”。
for name in names.into_iter() {
//消耗集合,以便在每次迭代时提供准确的数据。一旦使用完了集合,就不再可以重复使用,因为它已在循环中“移动”。
match name {
"Ferris" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
......@@ -142,7 +145,8 @@ fn for_range() {
}
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {//可变地借用了集合的每个元素,从而允许在适当的位置修改集合。
for name in names.iter_mut() {
//可变地借用了集合的每个元素,从而允许在适当的位置修改集合。
*name = match name {
&mut "Ferris" => "There is a rustacean among us!",
_ => "Hello",
......@@ -156,10 +160,10 @@ fn match_case() {
let number = 13;
println!("Tell me about {}", number);
match number {
1 => println!("One!"),//仅匹配1
2 | 3 | 5 | 7 | 11 => println!("This is a prime"),//匹配2或3或5或7或11
13..=19 => println!("A teen"),//匹配13到19的数字
_ => println!("Ain't special"),//其他
1 => println!("One!"), //仅匹配1
2 | 3 | 5 | 7 | 11 => println!("This is a prime"), //匹配2或3或5或7或11
13..=19 => println!("A teen"), //匹配13到19的数字
_ => println!("Ain't special"), //其他
}
let boolean = true;
......@@ -202,17 +206,14 @@ fn match_enums() {
Color::Red => println!("The color is Red!"),
Color::Blue => println!("The color is Blue!"),
Color::Green => println!("The color is Green!"),
Color::RGB(r, g, b) =>
println!("Red: {}, green: {}, and blue: {}!", r, g, b),
Color::HSV(h, s, v) =>
println!("Hue: {}, saturation: {}, value: {}!", h, s, v),
Color::HSL(h, s, l) =>
println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l),
Color::CMY(c, m, y) =>
println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y),
Color::CMYK(c, m, y, k) =>
println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",
c, m, y, k),
Color::RGB(r, g, b) => println!("Red: {}, green: {}, and blue: {}!", r, g, b),
Color::HSV(h, s, v) => println!("Hue: {}, saturation: {}, value: {}!", h, s, v),
Color::HSL(h, s, l) => println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l),
Color::CMY(c, m, y) => println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y),
Color::CMYK(c, m, y, k) => println!(
"Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",
c, m, y, k
),
}
}
......@@ -321,7 +322,8 @@ fn if_let() {
if let Some(i) = emoticon {
println!("Matched {:?}!", i);
} else if i_like_letters {//lf let没匹配上
} else if i_like_letters {
//lf let没匹配上
println!("Didn't match a number. Let's go with a letter!");
} else {
println!("I don't like letters. Let's go with an emoticon :)!");
......@@ -352,7 +354,8 @@ fn if_let() {
}
let a = Foo::Bar;
if let Foo::Bar = a {//枚举没有注解#[derive(PartialEq)],则无法比较,使用传统的if,则失败,编译不过
if let Foo::Bar = a {
//枚举没有注解#[derive(PartialEq)],则无法比较,使用传统的if,则失败,编译不过
println!("a is foobar");
}
}
......@@ -371,7 +374,9 @@ fn while_let() {
optional = Some(i + 1);
}
}
_ => { break; }
_ => {
break;
}
}
}
......@@ -385,5 +390,5 @@ fn while_let() {
println!("`i` is `{:?}`. Try again.", i);
optional = Some(i + 1);
}
}//while let 无子语句
}
\ No newline at end of file
} //while let 无子语句
}
use std::fmt::{Display, Error, Formatter};
use std::fmt;
use std::fmt::{Display, Error, Formatter};
///println宏的使用
pub fn formatted_print() {
......@@ -7,9 +7,17 @@ pub fn formatted_print() {
println!("{} days", 31);
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
//命名参数
println!("{subject} {verb} {object}", object = "the lazy dog", subject = "the quick brown fox", verb = "jumps over");
println!(
"{subject} {verb} {object}",
object = "the lazy dog",
subject = "the quick brown fox",
verb = "jumps over"
);
// 在冒号后指定特殊输出格式
println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
println!(
"{} of {:b} people know binary, the other half doesn't",
1, 2
);
//右对齐,指定宽度6
println!("{number:>width$}", number = 1, width = 6);
//右对齐,宽度6,使用0填错
......@@ -30,12 +38,14 @@ pub fn formatted_print() {
}
//更好看
let peter = Person { name: "Peter", age: 27 };
let peter = Person {
name: "Peter",
age: 27,
};
println!("{:#?}", peter);
//自己实现fmt::Display或Debug特质
#[derive(Debug)]
struct MinMax(i64, i64);
......@@ -61,7 +71,11 @@ pub fn formatted_print() {
//实现自己的Debug
impl fmt::Debug for Point2D {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "Complex {} real: {}, imag: {} {}", "{", self.x, self.y, "}")
write!(
f,
"Complex {} real: {}, imag: {} {}",
"{", self.x, self.y, "}"
)
}
}
......@@ -75,7 +89,6 @@ pub fn formatted_print() {
println!("Debug: {:?}", point);
println!("Debug: {:?}", point);
testcase_list();
struct City {
......@@ -88,7 +101,15 @@ pub fn formatted_print() {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let lat_c = if self.lat >= 0.0 { 'N' } else { 'S' };
let lon_c = if self.lon >= 0.0 { 'E' } else { 'W' };
write!(f, "{}: {:.3}°{} {:.3}°{}", self.name, self.lat.abs(), lat_c, self.lon.abs(), lon_c)
write!(
f,
"{}: {:.3}°{} {:.3}°{}",
self.name,
self.lat.abs(),
lat_c,
self.lon.abs(),
lon_c
)
}
}
......@@ -107,23 +128,55 @@ pub fn formatted_print() {
//format!("{}", foo) -> "3735928559"
//format!("0x{:X}", foo) -> "0xDEADBEEF"
//format!("0o{:o}", foo) -> "0o33653337357"
write!(f, "RGB ({}, {}, {}) 0x{:0>2X}{:0>2X}{:0>2X} ", self.red, self.green, self.blue, self.red, self.green, self.blue)
write!(
f,
"RGB ({}, {}, {}) 0x{:0>2X}{:0>2X}{:0>2X} ",
self.red, self.green, self.blue, self.red, self.green, self.blue
)
//右对齐,补0,16进制打印
}
}
for city in [
City { name: "Dublin", lat: 53.347778, lon: -6.259722 },
City { name: "Oslo", lat: 59.95, lon: 10.75 },
City { name: "Vancouver", lat: 49.25, lon: -123.1 },
].iter() {
City {
name: "Dublin",
lat: 53.347778,
lon: -6.259722,
},
City {
name: "Oslo",
lat: 59.95,
lon: 10.75,
},
City {
name: "Vancouver",
lat: 49.25,
lon: -123.1,
},
]
.iter()
{
println!("{}", *city);
}
for color in [
Color { red: 128, green: 255, blue: 90 },
Color { red: 0, green: 3, blue: 254 },
Color { red: 0, green: 0, blue: 0 },
].iter() {
Color {
red: 128,
green: 255,
blue: 90,
},
Color {
red: 0,
green: 3,
blue: 254,
},
Color {
red: 0,
green: 0,
blue: 0,
},
]
.iter()
{
println!("{:#}", *color);
}
}
......@@ -137,8 +190,10 @@ pub fn testcase_list() {
let vec = &self.0;
write!(f, "[")?;
for (count, v) in vec.iter().enumerate() {
if count != 0 { write!(f, ", ")?; }
write!(f, "{}: {}", count, v)?;//打印索引和数据
if count != 0 {
write!(f, ", ")?;
}
write!(f, "{}: {}", count, v)?; //打印索引和数据
}
write!(f, "]")
}
......
......@@ -107,4 +107,3 @@ fn methods() {
pair.destroy();
}
......@@ -103,22 +103,38 @@ fn bounds() {
fn area(&self) -> f64;
}
impl HasArea for Rectangle {
fn area(&self) -> f64 { self.length * self.height }
fn area(&self) -> f64 {
self.length * self.height
}
}
#[derive(Debug)]
struct Rectangle { length: f64, height: f64 }
struct Rectangle {
length: f64,
height: f64,
}
#[allow(dead_code)]
struct Triangle { length: f64, height: f64 }
struct Triangle {
length: f64,
height: f64,
}
//泛型“T”必须实现“Debug”
fn print_debug<T: Debug>(t: &T) {
println!("{:?}", t);
}
//必须实现HasArea
fn area<T: HasArea>(t: &T) -> f64 { t.area() }
fn area<T: HasArea>(t: &T) -> f64 {
t.area()
}
let rectangle = Rectangle { length: 3.0, height: 4.0 };
let _triangle = Triangle { length: 3.0, height: 4.0 };
let rectangle = Rectangle {
length: 3.0,
height: 4.0,
};
let _triangle = Triangle {
length: 3.0,
height: 4.0,
};
print_debug(&rectangle);
println!("Area: {}", area(&rectangle));
//print_debug(&_triangle);
......@@ -136,8 +152,12 @@ fn bounds() {
impl Blue for BlueJay {}
//这些函数仅对实现这些特性的类型有效。这些特征都是空的,这一事实无关紧要。
fn red<T: Red>(_: &T) -> &'static str { "red" }
fn blue<T: Blue>(_: &T) -> &'static str { "blue" }
fn red<T: Red>(_: &T) -> &'static str {
"red"
}
fn blue<T: Blue>(_: &T) -> &'static str {
"blue"
}
let cardinal = Cardinal;
let blue_jay = BlueJay;
let _turkey = Turkey;
......@@ -175,7 +195,10 @@ fn where_clauses() {
fn print_in_option(self);
}
impl<T> PrintInOption for T where Option<T>: Debug {
impl<T> PrintInOption for T
where
Option<T>: Debug,
{
fn print_in_option(self) {
println!("{:?}", Some(self));
}
......@@ -200,18 +223,29 @@ fn associated_types() {
fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
(&self.0 == number_1) && (&self.1 == number_2)
}
fn first(&self) -> i32 { self.0 }
fn last(&self) -> i32 { self.1 }
fn first(&self) -> i32 {
self.0
}
fn last(&self) -> i32 {
self.1
}
}
//必须显示声明所有泛型
fn difference<A, B, C>(container: &C) -> i32 where
C: Contains<A, B> {
fn difference<A, B, C>(container: &C) -> i32
where
C: Contains<A, B>,
{
container.last() - container.first()
}
let number_1 = 3;
let number_2 = 10;
let container = Container(number_1, number_2);
println!("Does container contain {} and {}: {}", &number_1, &number_2, container.contains(&number_1, &number_2));
println!(
"Does container contain {} and {}: {}",
&number_1,
&number_2,
container.contains(&number_1, &number_2)
);
println!("First number: {}", container.first());
println!("Last number: {}", container.last());
println!("The difference is: {}", difference(&container));
......@@ -235,8 +269,12 @@ fn associated_types() {
fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
(&self.0 == number_1) && (&self.1 == number_2)
}
fn first(&self) -> i32 { self.0 }
fn last(&self) -> i32 { self.1 }
fn first(&self) -> i32 {
self.0
}
fn last(&self) -> i32 {
self.1
}
}
//使用关联类型后定义更加简洁
fn difference<C: Contains>(container: &C) -> i32 {
......@@ -245,7 +283,12 @@ fn associated_types() {
let number_1 = 3;
let number_2 = 10;
let container = Container(number_1, number_2);
println!("Does container contain {} and {}: {}", &number_1, &number_2, container.contains(&number_1, &number_2));
println!(
"Does container contain {} and {}: {}",
&number_1,
&number_2,
container.contains(&number_1, &number_2)
);
println!("First number: {}", container.first());
println!("Last number: {}", container.last());
println!("The difference is: {}", difference(&container));
......@@ -259,8 +302,8 @@ fn associated_types() {
//标记拥有关系;
//自动trait实现(send/sync);
fn phantom_type_parameters() {
use std::ops::Add;
use std::marker::PhantomData;
use std::ops::Add;
#[derive(Debug, Clone, Copy)]
enum Inch {}
#[derive(Debug, Clone, Copy)]
......@@ -287,4 +330,4 @@ fn phantom_type_parameters() {
println!("one foot + one_foot = {:?} in", two_feet.0);
println!("one meter + one_meter = {:?} mm", two_meters.0);
//let one_feter = one_foot + one_meter;//error 2个相加的类型的泛型不同
}
\ No newline at end of file
}
......@@ -15,18 +15,18 @@ use crate::traits::*;
use crate::types::*;
use crate::variable_bindings::*;
pub mod closures;
pub mod conversion;
pub mod custom_types;
pub mod flow_control;
pub mod formatted_print;
pub mod misc;
pub mod traits;
pub mod functions;
pub mod generics;
pub mod misc;
pub mod modules;
pub mod functions;
pub mod flow_control;
pub mod closures;
pub mod conversion;
pub mod types;
pub mod primitives;
pub mod custom_types;
pub mod traits;
pub mod types;
pub mod variable_bindings;
///为了方便将每个知识点分为单独的源文件,并提供与之相同的公开方法测试内部所有代码
......
......@@ -32,7 +32,7 @@ fn threads() {
for child in children {
//等待线程完成,返回结果。_ 匿名变量,不需要这个结果
let _ = child.join();//按顺序从0~9打印
let _ = child.join(); //按顺序从0~9打印
}
}
......@@ -63,14 +63,16 @@ fn thread_testcase() {
// TODO: try removing the 'move' and see what happens
children.push(thread::spawn(move || -> u32 {
//转化为数字并计算此段的中间和
let result = data_segment.chars().map(|c| c.to_digit(10).expect("should be a digit")).sum();
let result = data_segment
.chars()
.map(|c| c.to_digit(10).expect("should be a digit"))
.sum();
println!("processed segment {}, result={}", i, result);
//每个子线程都返回中间结果
result
}));
}
//将每个线程的中间结果收集到一个新的Vec中
let mut intermediate_sums = vec![];
for child in children {
......@@ -87,8 +89,8 @@ fn thread_testcase() {
//通道
fn channels() {
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
use std::thread;
static NTHREADS: i32 = 3;
......@@ -210,7 +212,10 @@ fn file_read_lines() {
}
}
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>> where P: AsRef<Path>, {
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
//返回文件上的迭代器
Ok(io::BufReader::new(file).lines())
......@@ -221,9 +226,10 @@ fn file_read_lines() {
fn child_processes() {
use std::process::Command;
let output = Command::new("rustc").arg("--version").output().unwrap_or_else(|e| {
panic!("failed to execute process: {}", e)
});
let output = Command::new("rustc")
.arg("--version")
.output()
.unwrap_or_else(|e| panic!("failed to execute process: {}", e));
if output.status.success() {
let s = String::from_utf8_lossy(&output.stdout);
......@@ -246,7 +252,8 @@ fn child_processes_pipes() {
let process = match Command::new("wc")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn() {
.spawn()
{
Err(why) => panic!("couldn't spawn wc: {}", why.description()),
Ok(process) => process,
};
......@@ -350,9 +357,11 @@ fn filesystem_operations() {
// Read the contents of a directory, returns `io::Result<Vec<Path>>`
match fs::read_dir("a") {
Err(why) => println!("! {:?}", why.kind()),
Ok(paths) => for path in paths {
println!("> {:?}", path.unwrap().path());
},
Ok(paths) => {
for path in paths {
println!("> {:?}", path.unwrap().path());
}
}
}
println!("`rm a/c/e.txt`");
......@@ -393,11 +402,13 @@ fn argument_parsing() {
}
fn help() {
println!("usage:
println!(
"usage:
match_args <string>
Check whether given string is the answer.
match_args {{increase|decrease}} <integer>
Increase or decrease given integer by one.");
Increase or decrease given integer by one."
);
}
let args: Vec<String> = env::args().collect();
......@@ -405,20 +416,16 @@ match_args {{increase|decrease}} <integer>
1 => {
println!("My name is 'match_args'. Try passing some arguments!");
}
2 => {
match args[1].parse() {
Ok(42) => println!("This is the answer!"),
_ => println!("This is not the answer."),
}
}
2 => match args[1].parse() {
Ok(42) => println!("This is the answer!"),
_ => println!("This is not the answer."),
},
3 => {
let cmd = &args[1];
let num = &args[2];
// parse the number
let number: i32 = match num.parse() {
Ok(n) => {
n
}
Ok(n) => n,
Err(_) => {
eprintln!("error: second argument not an integer");
help();
......@@ -446,7 +453,7 @@ fn foreign_function_interface() {
//这个外部块链接到libm库
#[link(name = "m")]
extern {
extern "C" {
fn csqrtf(z: Complex) -> Complex;
fn ccosf(z: Complex) -> Complex;
......@@ -483,4 +490,4 @@ fn foreign_function_interface() {
println!("the square root of {:?} is {:?}", z, z_sqrt);
println!("cos({:?}) = {:?}", z, cos(z));
}
\ No newline at end of file
}
......@@ -12,7 +12,7 @@ fn struct_visibility() {
}
//公有结构体和私有字段
#[allow(dead_code)]//禁用编译器的 未使用警告
#[allow(dead_code)] //禁用编译器的 未使用警告
pub struct ClosedBox<T> {
contents: T,
}
......@@ -20,14 +20,14 @@ fn struct_visibility() {
impl<T> ClosedBox<T> {
//公有的构造函数
pub fn new(contents: T) -> ClosedBox<T> {
ClosedBox {
contents: contents,
}
ClosedBox { contents: contents }
}
}
}
let open_box = my::OpenBox { contents: "public information" };
let open_box = my::OpenBox {
contents: "public information",
};
println!("The open box contains: {}", open_box.contents);
//ERROR
......@@ -67,9 +67,10 @@ fn cfg() {
are_you_on_linux2();
println!("Are you sure?");
if cfg!(target_os = "linux") {//target_os由rustc隐式提供,但是自定义条件条件必须使用--cfg标志传递给rustc
if cfg!(target_os = "linux") {
//target_os由rustc隐式提供,但是自定义条件条件必须使用--cfg标志传递给rustc
println!("Yes. It's definitely linux!");
} else {
println!("Yes. It's definitely *not* linux!");
}
}
\ No newline at end of file
}
......@@ -17,7 +17,9 @@ fn tuples() {
struct Matrix(f32, f32, f32, f32);
//一组不同类型的元组
let long_tuple = (1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true);
let long_tuple = (
1u8, 2u16, 3u32, 4u64, -1i8, -2i16, -3i32, -4i64, 0.1f32, 0.2f64, 'a', true,
);
//可以使用元组索引从元组中提取值
println!("long tuple first value: {}", long_tuple.0);
......@@ -41,7 +43,7 @@ fn tuples() {
//要创建含有一个元素的元组,需要逗号来区分它们
// from a literal surrounded by parentheses
println!("one element tuple: {:?}", (5u32, ));
println!("one element tuple: {:?}", (5u32,));
println!("just an integer: {:?}", (5u32));
//元组可以被解构以创建绑定
......@@ -89,4 +91,4 @@ fn arrays_and_slices() {
//索引越界导致编译错误
//println!("{}", xs[5]);
}
\ No newline at end of file
}
///特质
pub fn traits() {
struct Sheep { naked: bool, name: &'static str }
struct Sheep {
naked: bool,
name: &'static str,
}
impl Sheep {
fn is_naked(&self) -> bool {
......@@ -36,7 +39,10 @@ pub fn traits() {
impl Animal for Sheep {
//self的类型是`Sheep`
fn new(name: &'static str) -> Sheep {
Sheep { name: name, naked: false }
Sheep {
name: name,
naked: false,
}
}
fn name(&self) -> &'static str {
......@@ -65,7 +71,6 @@ pub fn traits() {
dolly.shear();
dolly.talk();
//
derive();
return_dyn();
......@@ -79,7 +84,6 @@ pub fn traits() {
overlapping_traits();
}
fn derive() {
//比较特质: Eq, PartialEq, Ord, PartialOrd.
//拷贝特质(深拷贝), to create T from &T via a copy.
......@@ -118,12 +122,11 @@ fn derive() {
let meter = Centimeters(100.0);
let cmp =
if foot.to_centimeters() < meter {
"smaller"
} else {
"bigger"
};
let cmp = if foot.to_centimeters() < meter {
"smaller"
} else {
"bigger"
};
println!("One foot is {} than one meter.", cmp);
}
......@@ -163,7 +166,10 @@ fn return_dyn() {
let random_number = 0.234;
let animal = random_animal(random_number);
println!("You've randomly chosen an animal, and it says {}", animal.noise());
println!(
"You've randomly chosen an animal, and it says {}",
animal.noise()
);
}
fn operator_overload() {
......@@ -306,12 +312,15 @@ fn impl_trait() {
use std::vec::IntoIter;
//组合vec
fn combine_vecs_explicit_return_type(v: Vec<i32>, u: Vec<i32>) -> iter::Cycle<iter::Chain<IntoIter<i32>, IntoIter<i32>>> {
fn combine_vecs_explicit_return_type(
v: Vec<i32>,
u: Vec<i32>,
) -> iter::Cycle<iter::Chain<IntoIter<i32>, IntoIter<i32>>> {
v.into_iter().chain(u.into_iter()).cycle()
}
//简化返回类型
fn combine_vecs(v: Vec<i32>, u: Vec<i32>) -> impl Iterator<Item=i32> {
fn combine_vecs(v: Vec<i32>, u: Vec<i32>) -> impl Iterator<Item = i32> {
v.into_iter().chain(u.into_iter()).cycle()
}
......@@ -328,14 +337,14 @@ fn impl_trait() {
fn closure_trait() {
fn make_adder_function(y: i32) -> impl Fn(i32) -> i32 {
let closure = move |x: i32| { x + y };
let closure = move |x: i32| x + y;
closure
}
let plus_one = make_adder_function(1);
assert_eq!(plus_one(2), 3);
fn double_positives<'a>(numbers: &'a Vec<i32>) -> impl Iterator<Item=i32> + 'a {
fn double_positives<'a>(numbers: &'a Vec<i32>) -> impl Iterator<Item = i32> + 'a {
numbers.iter().filter(|x| x > &&0).map(|x| x * 2)
}
}
......@@ -443,4 +452,4 @@ fn overlapping_traits() {
let age = <Form as AgeWidget>::get(&form);
assert_eq!(28, age);
}
\ No newline at end of file
}
......@@ -46,4 +46,4 @@ fn literals() {
println!("size of `z` in bytes: {}", std::mem::size_of_val(&z));
println!("size of `i` in bytes: {}", std::mem::size_of_val(&i));
println!("size of `f` in bytes: {}", std::mem::size_of_val(&f));
}
\ No newline at end of file
}
......@@ -17,7 +17,6 @@ pub fn variable_bindings() {
let noisy_unused_variable = 2u32;
//可变
let _immutable_binding = 1;
let mut mutable_binding = 1;
......@@ -78,4 +77,4 @@ fn declare_first() {
another_binding = 1;
println!("another binding: {}", another_binding);
}
\ No newline at end of file
}
......@@ -13,11 +13,7 @@ pub fn closures_syntax() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout4(
simulated_user_specified_value,
simulated_random_number,
);
generate_workout4(simulated_user_specified_value, simulated_random_number);
///初始版本
fn generate_workout(intensity: u32, random_number: u32) {
......@@ -44,26 +40,16 @@ pub fn closures_syntax() {
///将调研提取到一个地方,存储在expensive_result变量中
fn generate_workout2(intensity: u32, random_number: u32) {
let expensive_result =
simulated_expensive_calculation(intensity);
let expensive_result = simulated_expensive_calculation(intensity);
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_result
);
println!(
"Next, do {} situps!",
expensive_result
);
println!("Today, do {} pushups!", expensive_result);
println!("Next, do {} situps!", expensive_result);
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_result
);
println!("Today, run for {} minutes!", expensive_result);
}
}
}
......@@ -71,29 +57,21 @@ pub fn closures_syntax() {
///使用闭包重构以存储代码
fn generate_workout3(intensity: u32, random_number: u32) {
///定义一个闭包并将其存储在 expensive_closure变量中
let expensive_closure = |num| {//如果我们有多个参数,则将它们用逗号分隔,例如|param1, param2|,显示定义类型:|num: u32| -> u32
let expensive_closure = |num| {
//如果我们有多个参数,则将它们用逗号分隔,例如|param1, param2|,显示定义类型:|num: u32| -> u32
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_closure(intensity)
);
println!(
"Next, do {} situps!",
expensive_closure(intensity)
);
println!("Today, do {} pushups!", expensive_closure(intensity));
println!("Next, do {} situps!", expensive_closure(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_closure(intensity)
);
println!("Today, run for {} minutes!", expensive_closure(intensity));
}
}
}
......@@ -106,14 +84,8 @@ pub fn closures_syntax() {
num
});
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_result.value(intensity)
);
println!(
"Next, do {} situps!",
expensive_result.value(intensity)
);
println!("Today, do {} pushups!", expensive_result.value(intensity));
println!("Next, do {} situps!", expensive_result.value(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
......@@ -126,10 +98,12 @@ pub fn closures_syntax() {
}
}
fn add_one_v1(x: u32) -> u32 { x + 1 }//显示函数定义
let add_one_v2 = |x: u32| -> u32 { x + 1 };//完整注释的闭包定义
let add_one_v3 = |x: u32| { x + 1 };//删除类型,没有使用该闭包时不加u32会报错
let add_one_v4 = |x: u32| x + 1;//删除括号,没有使用该闭包时不加u32会报错
fn add_one_v1(x: u32) -> u32 {
x + 1
} //显示函数定义
let add_one_v2 = |x: u32| -> u32 { x + 1 }; //完整注释的闭包定义
let add_one_v3 = |x: u32| x + 1; //删除类型,没有使用该闭包时不加u32会报错
let add_one_v4 = |x: u32| x + 1; //删除括号,没有使用该闭包时不加u32会报错
///两次使用闭包传入了不同类型参数,将会报错
///如果尝试对同一闭包使用其他不同类型,则会收到类型错误。
......@@ -152,14 +126,19 @@ pub fn closures_syntax() {
}
///定义一个包含闭包的结构,闭包类型Fn(u32) -> u32
struct Cacher<T> where T: Fn(u32) -> u32 {
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: Option<u32>,
}
///实现结构
impl<T> Cacher<T> where T: Fn(u32) -> u32 {
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
//没有执行时默认是None
Cacher {
......@@ -191,5 +170,5 @@ fn call_with_different_values() {
//失败
let v2 = c.value(2);
assert_ne!(v2, 2);//不等!!!!
}
\ No newline at end of file
assert_ne!(v2, 2); //不等!!!!
}
......@@ -3,38 +3,37 @@ use std::string::ToString;
///https://doc.rust-lang.org/stable/nomicon/vec.html.
///集合
pub fn collection_function() {
let mut v: Vec<i32> = Vec::new();//Vec类似ArrayList,称为向量?
v.push(12);//想要修改必须定义为mut可变的
let mut v: Vec<i32> = Vec::new(); //Vec类似ArrayList,称为向量?
v.push(12); //想要修改必须定义为mut可变的
println!("{:#?}", v);
let v = vec![1, 2, 3];
println!("{:#?}", v);
let v = vec![1, 2, 3, 4, 5];
let third = &v[2];//获取元素
let third = &v[2]; //获取元素
println!("The third element is {}", third);
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
//let does_not_exist = &v[100];//恐慌,编译时直接退出程序
///当将get方法传递给向量之外的索引时,它将返回None且不会出现惊慌。如果在正常情况下偶尔访问超出向量范围的元素,则可以使用此方法。
///您的代码将需要具有处理Some(&element)或None的逻辑,
let does_not_exist = v.get(100);
///当程序具有有效的引用时,借位检查器将执行所有权和借用规则
let mut v = vec![1, 2, 3, 4, 5];
let first = v[0];//使用引用&v[0]将会报错
v.push(6);//尝试保留第一个元素的引用的同时向向量添加元素将会出现编译错误,此时引用可能改变
let first = v[0]; //使用引用&v[0]将会报错
v.push(6); //尝试保留第一个元素的引用的同时向向量添加元素将会出现编译错误,此时引用可能改变
println!("The first element is: {}", first);
///遍历向量集合
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);//直接打印 i,而不需要使用c语言中的*i,省略了*
println!("{}", i); //直接打印 i,而不需要使用c语言中的*i,省略了*
}
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;//对可变的向量进行操作,让每个元素都增加50
*i += 50; //对可变的向量进行操作,让每个元素都增加50
println!("{}", i)
}
......@@ -65,7 +64,7 @@ pub fn collection_function() {
println!("{}", s);
let s = "initial contents".to_string();
println!("{}", s);
let s = String::from("initial contents");//从字符串文字(字符串常量 切片 &str类型)创建字符串(对象/String类型)
let s = String::from("initial contents"); //从字符串文字(字符串常量 切片 &str类型)创建字符串(对象/String类型)
println!("{}", s);
//其他编码的文字
let hello = String::from("السلام عليكم");
......@@ -86,16 +85,16 @@ pub fn collection_function() {
let mut s1 = String::from("foo");
let s2 = "bar";
s1.push_str(s2);
println!("s2 is {}", s2);//s2被加到s1之后,再次使用s2
println!("s2 is {}", s2); //s2被加到s1之后,再次使用s2
let mut s = String::from("lo");
s.push('l');//使用push向字符串值添加一个字符
s.push('l'); //使用push向字符串值添加一个字符
///合并字符串
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; //s1被移动,之后无法再次使用
//+ 方法 使用add方法 fn add(self, s: &str) -> String {
//所以+组合字符串第二个参数必须是 &str的,但是这是因为编译器将&String转化为&str了。
//+ 方法 使用add方法 fn add(self, s: &str) -> String {
//所以+组合字符串第二个参数必须是 &str的,但是这是因为编译器将&String转化为&str了。
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
......@@ -124,10 +123,10 @@ pub fn collection_function() {
///但是用String不能保证性能,因为Rust必须从头到尾遍历所有内容以确定有多少个有效字符。
///有效的Unicode标量值可能由1个以上的字节组成,从rust字符串中获取字素簇很复杂,标准库并未提供此功能
for c in "नमस्ते".chars() {
println!("{}", c);//न म स ् त े ,一个字符由2个char组成
println!("{}", c); //न म स ् त े ,一个字符由2个char组成
}
for b in "नमस्ते".bytes() {
println!("{}", b);//返回字节,很多个
println!("{}", b); //返回字节,很多个
}
///hash map
......@@ -144,7 +143,7 @@ pub fn collection_function() {
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();
map.insert(field_name, field_value);//此时field_name和field_value无效,已经被移动到map中
map.insert(field_name, field_value); //此时field_name和field_value无效,已经被移动到map中
///获取key对应的value
let team_name = String::from("Blue");
let score = scores.get(&team_name);
......@@ -164,4 +163,4 @@ pub fn collection_function() {
}
println!("{:?}", map);
}//v超出范围并在此处释放
} //v超出范围并在此处释放
......@@ -9,7 +9,7 @@ pub fn control_function() {
}
///处理多个if
let number = 6;//阴影,遮盖了前面的number
let number = 6; //阴影,遮盖了前面的number
if number % 4 == 0 {
println!("number is divisible by 4");
......@@ -24,18 +24,14 @@ pub fn control_function() {
///与Scala一样,可以将if表达式的结果赋值给变量(这里的变量一般是指不可变的变量,虽然绕口,但是确实是事实)
let condition = true;
///从每个分支取得的if的返回值必须是同一类型,否则编译报错
let number = if condition {
5
} else {
6
};
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
///循环
loop {
println!("again!");
break;//这个分号可省
break; //这个分号可省
}
///从循环中返回值
let mut counter = 0;
......@@ -44,7 +40,7 @@ pub fn control_function() {
counter += 1;
if counter == 10 {
break counter * 2;
};//这个分号可省
}; //这个分号可省
};
///分号的使用还不清晰明确,后面再看
......@@ -57,7 +53,7 @@ pub fn control_function() {
while number != 0 {
println!("{}!", number);
number -= 1;
};//这个分号可以省略
} //这个分号可以省略
println!("LIFTOFF!!!");
///while变量数组
......@@ -83,4 +79,4 @@ pub fn control_function() {
print!("{}!", number);
}
println!("LIFTOFF!!!");
}
\ No newline at end of file
}
......@@ -31,7 +31,6 @@ pub fn enum_data_type() {
address: String::from("::1"),
};
///数值直接放入每个枚举变量中,而不是需要使用结构体 struct IpAddr
enum IpAddr2 {
V4(String),
......
......@@ -15,12 +15,14 @@ pub fn example_guessing_game() {
println!("Please input your guess.");
//变量默认是不可变的。使用mut表示变量是可变的,定义成let foo = 5; 则是不可变。
let mut guess = String::new();//关联函数,在类型上实现。一些语言称为静态方法。该函数创建了一个空串
let mut guess = String::new(); //关联函数,在类型上实现。一些语言称为静态方法。该函数创建了一个空串
//没有使用use,则这里需要写成 std::io::stdin
//&表示该参数是一个引用,Rust的主要优势之一是使用引用的安全性和便捷性
//&使您代码的多个部分可以访问同一条数据,而无需将该数据多次复制到内存中
io::stdin().read_line(&mut guess).expect("Failed to read line");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
//无法比较数值与字符串需要转化为数值,Rust默认为i32
//Rust允许我们用新的值遮盖以前的值guess。此功能通常用于要将值从一种类型转换为另一种类型的情况。
......@@ -48,4 +50,4 @@ pub fn example_guessing_game() {
}
}
}
}
\ No newline at end of file
}
......@@ -4,4 +4,4 @@ pub mod hosting;
//Rust会查找 src/hosting.rs(同名文件) 或者 src/hosting/mod.rs,mod不再包含子模块则使用src/hosting.rs,否则使用src/hosting/mod.rs
pub fn add_to_waitlist() {
hosting::add_to_waitlist_host();
}
\ No newline at end of file
}
//hosting是front_of_house的子模块,hosting在front_of_house的文件夹里面,使用fn公开方法
pub fn add_to_waitlist_host() {
println!("hello world aaaaaaaaaaaa")
}
\ No newline at end of file
}
......@@ -2,7 +2,6 @@ use std::fmt::{Debug, Display};
///通用类型,特征和寿命
pub fn largest_function() {
//在数字列表中查找最大数字的代码
let number_list = vec![34, 50, 25, 100, 65];
......@@ -200,9 +199,17 @@ pub fn trait_function() {
}
///这样写太麻烦
fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 { 1 }
fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 {
1
}
//简化
fn some_function2<T, U>(t: T, u: U) -> i32 where T: Display + Clone, U: Clone + Debug { 1 }
fn some_function2<T, U>(t: T, u: U) -> i32
where
T: Display + Clone,
U: Clone + Debug,
{
1
}
///返回实现特征的类型
fn returns_summarizable() -> impl Summary {
......@@ -215,24 +222,24 @@ pub fn trait_function() {
}
//下面是无效的,编译不过
//由于在编译器中实现impl Trait语法方面的限制,因此不允许返回NewsArticle或Tweet
// fn returns_summarizable2(switch: bool) -> impl Summary {
// if switch {
// NewsArticle {
// headline: String::from("Penguins win the Stanley Cup Championship!"),
// location: String::from("Pittsburgh, PA, USA"),
// author: String::from("Iceburgh"),
// content: String::from("The Pittsburgh Penguins once again are the best
// hockey team in the NHL."),
// }
// } else {
// Tweet {
// username: String::from("horse_ebooks"),
// content: String::from("of course, as you probably already know, people"),
// reply: false,
// retweet: false,
// }
// }
// }
// fn returns_summarizable2(switch: bool) -> impl Summary {
// if switch {
// NewsArticle {
// headline: String::from("Penguins win the Stanley Cup Championship!"),
// location: String::from("Pittsburgh, PA, USA"),
// author: String::from("Iceburgh"),
// content: String::from("The Pittsburgh Penguins once again are the best
// hockey team in the NHL."),
// }
// } else {
// Tweet {
// username: String::from("horse_ebooks"),
// content: String::from("of course, as you probably already know, people"),
// reply: false,
// retweet: false,
// }
// }
// }
struct Pair<T> {
x: T,
......@@ -240,10 +247,7 @@ pub fn trait_function() {
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self {
x,
y,
}
Self { x, y }
}
}
///始终实现new函数,但是Pair<T>仅在内部类型T实现了实现比较的PartialOrd特质和实现打印的Display特质的情况下,才实现cmp_display方法。
......@@ -261,38 +265,38 @@ pub fn trait_function() {
///生命周期
fn lifetimes_function() {
//使用生命周期验证引用
//在大多数情况下,生存期是隐式和推断的,就像在大多数情况下一样,推断类型。
//当可能有多个类型时,必须注释类型。以类似的方式,当引用的生存期可以通过几种不同方式关联时,我们必须注释生存期。
//Rust要求我们使用通用生命周期参数注释关系,以确保在运行时使用的实际引用绝对有效。
//生命周期的主要目的是防止引用悬而未决,从而导致程序引用的数据不是其要引用的数据。
// {
// r和x的生命周期注释,分别命名为'a和'b
// let r; // ---------+-- 'a
// |
// { // |
// let x = 5; // -+-- 'b |
// r = &x; // | |
// } // -+ |
// |
// println!("r: {}", r); // |
// } // ----------+
//使用生命周期验证引用
//在大多数情况下,生存期是隐式和推断的,就像在大多数情况下一样,推断类型。
//当可能有多个类型时,必须注释类型。以类似的方式,当引用的生存期可以通过几种不同方式关联时,我们必须注释生存期。
//Rust要求我们使用通用生命周期参数注释关系,以确保在运行时使用的实际引用绝对有效。
//生命周期的主要目的是防止引用悬而未决,从而导致程序引用的数据不是其要引用的数据。
// {
// r和x的生命周期注释,分别命名为'a和'b
// let r; // ---------+-- 'a
// |
// { // |
// let x = 5; // -+-- 'b |
// r = &x; // | |
// } // -+ |
// |
// println!("r: {}", r); // |
// } // ----------+
///正确代码
{
let x = 5; // ----------+-- 'b
// |
let r = &x; // --+-- 'a |
// | |
let x = 5; // ----------+-- 'b
// |
let r = &x; // --+-- 'a |
// | |
println!("r: {}", r); // | |
// --+ |
} // ----------+
} // ----------+
///函数的通用生命周期
///过于复杂,建议有时间再研究:https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html
// &i32 // 一个引用
// &'a i32 // 具有明确生命周期的引用
// &'a mut i32 // 具有显式寿命的可变引用
// &i32 // 一个引用
// &'a i32 // 具有明确生命周期的引用
// &'a mut i32 // 具有显式寿命的可变引用
///指定签名中的所有引用必须具有相同的生存期 'a
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
......@@ -302,5 +306,3 @@ fn lifetimes_function() {
}
}
}
......@@ -7,7 +7,6 @@ pub fn iterator_function() {
println!("{}", v2 == vec![2, 3, 4])
}
struct Counter {
count: u32,
}
......@@ -42,7 +41,6 @@ fn calling_next_directly() {
assert_eq!(counter.next(), None);
}
#[derive(PartialEq, Debug)]
struct Shoe {
size: u32,
......@@ -57,21 +55,35 @@ fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
#[test]
fn filters_by_size() {
let shoes = vec![
Shoe { size: 10, style: String::from("sneaker") },
Shoe { size: 13, style: String::from("sandal") },
Shoe { size: 10, style: String::from("boot") },
Shoe {
size: 10,
style: String::from("sneaker"),
},
Shoe {
size: 13,
style: String::from("sandal"),
},
Shoe {
size: 10,
style: String::from("boot"),
},
];
let in_my_size = shoes_in_my_size(shoes, 10);
assert_eq!(
in_my_size,
vec![
Shoe { size: 10, style: String::from("sneaker") },
Shoe { size: 10, style: String::from("boot") },
Shoe {
size: 10,
style: String::from("sneaker")
},
Shoe {
size: 10,
style: String::from("boot")
},
]
);
}
#[test]
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
......@@ -93,9 +105,10 @@ fn iterator_sum() {
#[test]
fn using_other_iterator_trait_methods() {
let sum: u32 = Counter::new().zip(Counter::new().skip(1))
let sum: u32 = Counter::new()
.zip(Counter::new().skip(1))
.map(|(a, b)| a * b)
.filter(|x| x % 3 == 0)
.sum();
assert_eq!(18, sum);
}
\ No newline at end of file
}
......@@ -32,7 +32,7 @@ pub mod front_of_house;
//使用 pub公开模块的功能
pub fn eat_at_restaurant() {
// 使用绝对路径,更好
// crate::front_of_house::hosting::add_to_waitlist_host();
// crate::front_of_house::hosting::add_to_waitlist_host();
// 使用相对路径
front_of_house::hosting::add_to_waitlist_host();
}
......@@ -52,7 +52,7 @@ mod back_of_house {
pub struct Breakfast {
pub toast: String,
//该结构是公开的,且只有toast是公开的属性字段
seasonal_fruit: String,//无法更改
seasonal_fruit: String, //无法更改
}
impl Breakfast {
......@@ -72,14 +72,13 @@ mod back_of_house {
}
}
//mod front_of_house;//在mod front_of_house之后使用分号(而不是使用块)会告诉Rust从另一个与模块同名的文件中加载模块的内容。
//pub use 重新导出,使名称可用于新范围内的任何代码 (因为我们将一个项目放入范围内,同时也使该项目可供其他人进入其范围)
//use std::collections::*; //导入所有内部的类型
pub fn eat_at_restaurant2() {
let mut meal = back_of_house::Breakfast::summer("Rye");//关联函数 summer 用于构造实例
let mut meal = back_of_house::Breakfast::summer("Rye"); //关联函数 summer 用于构造实例
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
//下面编译不过,seasonal_fruit是私有的
......@@ -89,12 +88,12 @@ pub fn eat_at_restaurant2() {
let order2 = back_of_house::Appetizer::Salad;
//使用use导入模块,可以省略模块前缀,使代码简洁
front_of_house::hosting::add_to_waitlist_host();//front_of_house :: hosting 二级包
front_of_house::hosting::add_to_waitlist_host(); //front_of_house :: hosting 二级包
front_of_house::hosting::add_to_waitlist_host();
front_of_house::hosting::add_to_waitlist_host();
//use的习惯用法,但是不同模块中的相同函数,需要加模块前缀,如:fmt::Result,io::Result
use std::collections::HashMap as RustHashMap;//使用as为导入的类型提供别名,一般在最前面使用导入,这里为了方便
use std::collections::HashMap as RustHashMap; //使用as为导入的类型提供别名,一般在最前面使用导入,这里为了方便
let mut map = RustHashMap::new();
map.insert(1, 2);
}
\ No newline at end of file
}
......@@ -14,7 +14,7 @@
///}
///
///
#[macro_export]//#[macro_export]注解(注释)表示,只要将定义了该宏的板条箱放入范围内,就应使该宏可用。没有此注释,宏将无法进入范围。
#[macro_export] //#[macro_export]注解(注释)表示,只要将定义了该宏的板条箱放入范围内,就应使该宏可用。没有此注释,宏将无法进入范围。
macro_rules! Vec {//然后,我们从macro_rules! 开始宏定义!以及我们定义的不带感叹号的宏的名称。该名称(在本例中为Vec)后跟大括号,表示宏定义的正文。
( $( $x:expr ),* ) => {//模式与代码块,宏模式是针对Rust代码结构而非值进行匹配的
//首先一组括号()包括整个模式,这些括号捕获与括号内的模式匹配的值,以供替换代码使用
......@@ -33,6 +33,6 @@ macro_rules! Vec {//然后,我们从macro_rules! 开始宏定义!以及我
pub fn marco_function() {
///定义自己的宏。(标准库的是vec!)
let v: Vec<u32> = Vec![1, 2, 3];// $x 匹配 1,2,3 三次
println!("{}", v.len())//宏定义必须在前面
}
\ No newline at end of file
let v: Vec<u32> = Vec![1, 2, 3]; // $x 匹配 1,2,3 三次
println!("{}", v.len()) //宏定义必须在前面
}
......@@ -31,24 +31,24 @@ use struct_data_type::*;
use thread_syntax::*;
use variables_function::*;
pub mod panic_function;
pub mod thread_syntax;
pub mod closures_syntax;
pub mod collection_function;
pub mod control_function;
pub mod enum_data_type;
pub mod example_guessing_game;
pub mod generic_traits_lifetimes;
pub mod iterator_demonstration;
pub mod struct_data_type;
pub mod simple_array_data_type;
pub mod macro_syntax;
pub mod match_syntax;
pub mod example_guessing_game;
pub mod variables_function;
pub mod enum_data_type;
pub mod method_syntax;
pub mod collection_function;
pub mod point_function;
pub mod control_function;
pub mod other_function;
pub mod closures_syntax;
pub mod panic_function;
pub mod point_function;
pub mod simple_array_data_type;
pub mod smart_point;
pub mod macro_syntax;
pub mod struct_data_type;
pub mod thread_syntax;
pub mod variables_function;
/// 引用和借用:https://dreamylost.cn/rust/Rust-Rust%E5%AD%A6%E4%B9%A0%E4%B9%8B%E5%BC%95%E7%94%A8%E4%B8%8E%E5%80%9F%E7%94%A8.html
/// 所有权:https://dreamylost.cn/rust/Rust-%E6%89%80%E6%9C%89%E6%9D%83.html
......@@ -64,7 +64,7 @@ fn main() {
println!("====================");
expr_function();
println!("====================");
println!("{}", five());//打印字符串,不能直接println!(five())
println!("{}", five()); //打印字符串,不能直接println!(five())
println!("====================");
control_function();
println!("====================");
......
......@@ -3,7 +3,7 @@ pub fn match_syntax2() {
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => () //这行是多余的样板代码
_ => (), //这行是多余的样板代码
}
//使用if let 省略上面的样板代码
......@@ -65,7 +65,6 @@ pub fn match_syntax() {
}
}
///绑定到值的匹配
#[derive(Debug)]
enum UsState {
......@@ -112,6 +111,6 @@ pub fn match_syntax() {
3 => println!("three"),
5 => println!("five"),
7 => println!("seven"),
_ => ()
_ => (),
}
}
......@@ -21,11 +21,17 @@ pub fn method_syntax() {
//关联函数,没有self,类似其他语言的静态方法,但不是rust方法
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
Rectangle {
width: size,
height: size,
}
}
}
let rect1 = Rectangle { width: 30, height: 50 };
let rect1 = Rectangle {
width: 30,
height: 50,
};
///c/c++中如果object是一个指针, object->something() 与 (*object).something()等价
///Rust没有等效于->运算符;相反,Rust具有称为自动引用和取消引用的功能。调用方法是Rust少数具有这种行为的地方之一。
......@@ -38,9 +44,18 @@ pub fn method_syntax() {
);
///方法参数
let rect1 = Rectangle { width: 30, height: 50 };
let rect2 = Rectangle { width: 10, height: 40 };
let rect3 = Rectangle { width: 60, height: 45 };
let rect1 = Rectangle {
width: 30,
height: 50,
};
let rect2 = Rectangle {
width: 10,
height: 40,
};
let rect3 = Rectangle {
width: 60,
height: 45,
};
println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
......@@ -48,7 +63,7 @@ pub fn method_syntax() {
///impl块的另一个有用功能是允许我们在不以self为参数的impl块中定义函数。这些之所以称为关联函数,是因为它们与struct相关联。
///它们仍然是函数,而不是方法,因为它们没有可使用的结构实例
///关联函数通常用于将返回该结构的新实例的构造函数。例如,我们可以提供一个关联的函数,该函数将具有一个维度参数并将其用作宽度和高度,从而使创建矩形矩形变得更加容易,而不必两次指定相同的值:
let sq = Rectangle::square(3);//类似调用静态方法
let sq = Rectangle::square(3); //类似调用静态方法
println!("sq is {:#?}", sq);
///关联函数与结构体相关,但是没有self实例,他们仍是函数!!!
......@@ -61,4 +76,4 @@ pub fn method_syntax() {
let test = Test::test();
println!("test is {:#?}", test);
}
\ No newline at end of file
}
......@@ -12,23 +12,24 @@ pub fn crate_function() {
// lib::eat_at_restaurant2();
//}
pub fn return_function() {
let s1 = gives_ownership(); // lets_ownership移动其返回值到s1中
let s1 = gives_ownership(); // lets_ownership移动其返回值到s1中
let s2 = String::from("hello"); // s2进入范围
let s2 = String::from("hello"); // s2进入范围
let s3 = takes_and_gives_back(s2); // s2被移入takes_and_gives_back, takes_and_gives_back的返回值被移动到s3
let s3 = takes_and_gives_back(s2); // s2被移入takes_and_gives_back, takes_and_gives_back的返回值被移动到s3
println!("{},{}", s1, s3);
fn gives_ownership() -> String { // gives_ownership会其返回值移动到调用它的函数中
fn gives_ownership() -> String {
// gives_ownership会其返回值移动到调用它的函数中
let some_string = String::from("hello"); // some_string进入范围
some_string // 返回some_string字符串并移到调用函数
some_string // 返回some_string字符串并移到调用函数
}
// take_and_gives_back将获取一个String并返回一个
fn takes_and_gives_back(a_string: String) -> String { // a_string进入范围
a_string // 返回a_string并移至调用函数
fn takes_and_gives_back(a_string: String) -> String {
// a_string进入范围
a_string // 返回a_string并移至调用函数
}
}
......@@ -67,4 +68,4 @@ pub fn five() -> i32 {
pub fn another_function(x: i32) {
//传参数的rust函数,与Scala一样,名称: 类型
println!("The value of x is: {}", x);
}
\ No newline at end of file
}
use std::{fs, io};
use std::error::Error;
use std::fs::File;
use std::io::{ErrorKind, Read};
use std::{fs, io};
///恐慌使用(error)
pub fn panic_function() {
......@@ -11,7 +11,7 @@ pub fn panic_function() {
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),//panic!打印错误信息,panic是不可恢复的错误
Err(e) => panic!("Problem creating the file: {:?}", e), //panic!打印错误信息,panic是不可恢复的错误
},
other_error => panic!("Problem opening the file: {:?}", other_error),
},
......@@ -50,7 +50,7 @@ pub fn panic_function() {
///传播错误的捷径:?运算符
fn read_username_from_file2() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;//使用?运算符将错误返回到调用代码的函数,将错误自身转换为返回的错误类型。(From特质 from函数)
let mut f = File::open("hello.txt")?; //使用?运算符将错误返回到调用代码的函数,将错误自身转换为返回的错误类型。(From特质 from函数)
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
......@@ -83,12 +83,10 @@ pub fn panic_function() {
if value < 1 || value > 100 {
panic!("Guess value must be between 1 and 100, got {}.", value);
}
Guess {
value
}
Guess { value }
}
pub fn value(&self) -> i32 {
self.value
}
}
}
\ No newline at end of file
}
......@@ -2,11 +2,10 @@
///Rust中最常见的一种指针是引用,还有其他指针
///在使用所有权和借用概念的Rust中,引用和智能指针之间的另一个区别是,引用是仅借用数据的指针。相反,在许多情况下,智能指针拥有它们指向的数据。
pub fn empty_point_function() {
//let reference_to_nothing = dangle();
let reference_to_nothing = no_dangle();
fn no_dangle() -> String {
String::from("hello")// 直接反回函数的值,不能加分号
String::from("hello") // 直接反回函数的值,不能加分号
}
//编译报错,因为s是在dangle内部创建的,所以当dangle的代码完成时,将释放s。但是我们试图返回对它的引用。这意味着该引用将指向无效的String。Rust不允许我们这样做。
// fn dangle() -> &String {
......
......@@ -3,7 +3,6 @@ pub fn simple_array_data_type() {
///--release模式下,整数溢出将会变为最小值
///在u8(0-255)类型下,256变为0,257变为1,依此类推
///默认浮点类型是f64,相当于Java double,IEEE754标准
let x = 2.0; // f64
......@@ -60,7 +59,7 @@ pub fn simple_array_data_type() {
let second = a[1];
///Rust通过立即退出而不是允许内存访问并继续操作来保护您免受此类错误的侵害
let element = a[0];//若下标大于数组索引则运行时检查并报错退出"error: index out of bounds: the len is 5 but the index is 10"
let element = a[0]; //若下标大于数组索引则运行时检查并报错退出"error: index out of bounds: the len is 5 but the index is 10"
}
///rust String比较复杂
......@@ -70,16 +69,15 @@ pub fn string_function() {
println!("{}", s); //打印 hello, world!
let s = String::from("hello"); // s进入范围
let s = String::from("hello"); // s进入范围
takes_ownership(s); // s的值移动到函数,所以在这里不再有效
//println!("{}", s);//编译错误:value borrowed here after move。出借后的s被移动,后续不可用
takes_ownership(s); // s的值移动到函数,所以在这里不再有效
//println!("{}", s);//编译错误:value borrowed here after move。出借后的s被移动,后续不可用
let x = 5; // x进入范围
makes_copy(x); // x将移动到函数
//但是i32是Copy,所以之后还可以使用
println!("{}", x);//正常打印
let x = 5; // x进入范围
makes_copy(x); // x将移动到函数
//但是i32是Copy,所以之后还可以使用
println!("{}", x); //正常打印
fn takes_ownership(some_string: String) {
println!("{}", some_string);
......@@ -88,4 +86,4 @@ pub fn string_function() {
fn makes_copy(some_integer: i32) {
println!("{}", some_integer);
}
}
\ No newline at end of file
}
......@@ -43,7 +43,7 @@ pub fn box_function() {
&self.0
}
}
assert_eq!(5, *y);//*(y.deref()),如果该deref方法直接返回该值而不是对该值的引用,则该值将移出self。因为我们*操作时一般不需要拥有这个所有权
assert_eq!(5, *y); //*(y.deref()),如果该deref方法直接返回该值而不是对该值的引用,则该值将移出self。因为我们*操作时一般不需要拥有这个所有权
///隐式的强制实现deref特质
fn hello(name: &str) {
......@@ -52,7 +52,7 @@ pub fn box_function() {
let m = MyBox::new(String::from("Rust"));
hello(&m);
let m = MyBox::new(String::from("Rust"));
hello(&(*m)[..]);//如果Rust没有实现deref,代码应该写成这样(虽然两者都可用,但是这个更麻烦)
hello(&(*m)[..]); //如果Rust没有实现deref,代码应该写成这样(虽然两者都可用,但是这个更麻烦)
//由于有借用规则,如果您有可变引用,则该可变引用必须是对该数据的唯一引用(否则,程序将无法编译)。
//将一个可变引用转换为一个不可变引用将永远不会违反借用规则。
......@@ -62,7 +62,6 @@ pub fn box_function() {
//当T: DerefMut<Target=U> 从 &mut T 到 &mut U
//当T: Deref<Target=U> 从 &mut T 到 &U
///在实例超出范围时将打印该结构
struct CustomSmartPointer {
data: String,
......@@ -74,13 +73,19 @@ pub fn box_function() {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
let c = CustomSmartPointer { data: String::from("my stuff") };
let d = CustomSmartPointer { data: String::from("other stuff") };
let c = CustomSmartPointer {
data: String::from("my stuff"),
};
let d = CustomSmartPointer {
data: String::from("other stuff"),
};
println!("CustomSmartPointers created.");
let c = CustomSmartPointer { data: String::from("some data") };
let c = CustomSmartPointer {
data: String::from("some data"),
};
println!("CustomSmartPointer created.");
drop(c);//希望早点被删除,调用std::mem::drop在值超出范围之前显式删除它。与c++析构函数相同,drop只被调用一次
drop(c); //希望早点被删除,调用std::mem::drop在值超出范围之前显式删除它。与c++析构函数相同,drop只被调用一次
println!("CustomSmartPointer dropped before the end of main.");
///使用Rc<T>(引用计数)智能指针共享数据
......@@ -90,14 +95,14 @@ pub fn box_function() {
}
use ListRc::*;
let a = Rc::new(ConsRc(5, Rc::new(ConsRc(10, Rc::new(NilRc)))));
println!("count after creating a = {}", Rc::strong_count(&a));//引用计数=1
let b = ConsRc(3, Rc::clone(&a));//clone无额外性能开销,实际仅增加了引用计数而不是真的深拷贝数据
println!("count after creating b = {}", Rc::strong_count(&a));//引用计数=2
println!("count after creating a = {}", Rc::strong_count(&a)); //引用计数=1
let b = ConsRc(3, Rc::clone(&a)); //clone无额外性能开销,实际仅增加了引用计数而不是真的深拷贝数据
println!("count after creating b = {}", Rc::strong_count(&a)); //引用计数=2
{
let c = ConsRc(4, Rc::clone(&a));
println!("count after creating c = {}", Rc::strong_count(&a));//引用计数=3
}//超出范围了,引用计数变为2
println!("count after c goes out of scope = {}", Rc::strong_count(&a));//Weak 弱引用计数
println!("count after creating c = {}", Rc::strong_count(&a)); //引用计数=3
} //超出范围了,引用计数变为2
println!("count after c goes out of scope = {}", Rc::strong_count(&a)); //Weak 弱引用计数
//运行时执行检查不可变或可变的借用,RefCell<T>,因为RefCell<T>允许在运行时检查可变借位,所以即使RefCell<T>不可变,您也可以更改RefCell<T>内部的值。
//Box<T>允许在编译时检查不可变或可变的借用
......@@ -116,7 +121,10 @@ pub struct LimitTracker<'a, T: Messenger> {
max: usize,
}
impl<'a, T> LimitTracker<'a, T> where T: Messenger {
impl<'a, T> LimitTracker<'a, T>
where
T: Messenger,
{
pub fn new(messenger: &T, max: usize) -> LimitTracker<T> {
LimitTracker {
messenger,
......@@ -125,16 +133,17 @@ impl<'a, T> LimitTracker<'a, T> where T: Messenger {
}
}
pub fn set_value(&mut self, value: usize) {
self.value = value;
let percentage_of_max = self.value as f64 / self.max as f64;
if percentage_of_max >= 1.0 {
self.messenger.send("Error: You are over your quota!");
} else if percentage_of_max >= 0.9 {
self.messenger.send("Urgent warning: You've used up over 90% of your quota!");
self.messenger
.send("Urgent warning: You've used up over 90% of your quota!");
} else if percentage_of_max >= 0.75 {
self.messenger.send("Warning: You've used up over 75% of your quota!");
self.messenger
.send("Warning: You've used up over 75% of your quota!");
}
}
}
......@@ -149,20 +158,21 @@ mod tests {
struct MockMessenger {
//sent_messages: Vec<String>,
sent_messages: RefCell<Vec<String>>,
}
impl MockMessenger {
fn new() -> MockMessenger {
//MockMessenger { sent_messages: vec![] }
MockMessenger { sent_messages: RefCell::new(vec![]) }
MockMessenger {
sent_messages: RefCell::new(vec![]),
}
}
}
impl Messenger for MockMessenger {
fn send(&self, message: &str) {
//self.sent_messages.push(String::from(message));//编译报错
self.sent_messages.borrow_mut().push(String::from(message));//可变借用
self.sent_messages.borrow_mut().push(String::from(message)); //可变借用
}
}
......
......@@ -7,7 +7,8 @@ pub fn struct_data_type() {
active: bool,
}
let mut user1 = User { //必须定义为可变的才能修改结构体的内容
let mut user1 = User {
//必须定义为可变的才能修改结构体的内容
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
......@@ -73,7 +74,10 @@ pub fn struct_data_type() {
width * height
}
println!("The area of the rectangle is {} square pixels.", area(width1, height1));
println!(
"The area of the rectangle is {} square pixels.",
area(width1, height1)
);
//使用元祖
fn area_tuple(dimensions: (u32, u32)) -> u32 {
......@@ -98,12 +102,15 @@ pub fn struct_data_type() {
rectangle.width * rectangle.height
}
let rect1 = Rectangle { width: 30, height: 50 };
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
area_struct(&rect1)
);
//这将会报错,因为该结构体不支持显示:`Rectangle` doesn't implement `std::fmt::Display`
println!("rect1 is {:#?}", rect1);//{:?}使用调试模式打印也会报错:`Rectangle` doesn't implement `std::fmt::Debug`,{:#?} 格式化打印
}
\ No newline at end of file
println!("rect1 is {:#?}", rect1); //{:?}使用调试模式打印也会报错:`Rectangle` doesn't implement `std::fmt::Debug`,{:#?} 格式化打印
}
use std::sync::{Arc, mpsc, Mutex};
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
......@@ -13,7 +13,7 @@ pub fn create_thread() {
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));//短暂停止,最终仍取决于操作系统如何调度线程。
thread::sleep(Duration::from_millis(1)); //短暂停止,最终仍取决于操作系统如何调度线程。
}
}
......@@ -32,13 +32,14 @@ pub fn join_thread() {
thread::sleep(Duration::from_millis(1));
}
///阻塞当前正在运行的线程,直到由该句柄表示的线程终止
handle.join().unwrap();//即thread::spawn先执行,main后执行
handle.join().unwrap(); //即thread::spawn先执行,main后执行
}
pub fn use_var_thread() {
///尝试在另一个线程中使用由主线程创建的向量
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {//必须在闭包前加move,强制获取v变量的所有权而不是借用这个值
let handle = thread::spawn(move || {
//必须在闭包前加move,强制获取v变量的所有权而不是借用这个值
println!("Here's a vector: {:?}", v);
});
//v不能再被主线程使用,所有权已经转移
......@@ -56,7 +57,7 @@ pub fn channel_thread() {
tx.send(val).unwrap();
});
//使用rx接收器接收消息
let received = rx.recv().unwrap();//try_recv方法不会阻塞
let received = rx.recv().unwrap(); //try_recv方法不会阻塞
println!("Got: {}", received);
}
......@@ -150,4 +151,3 @@ pub fn mutex_multi_thread() {
}
println!("Result: {}", *counter.lock().unwrap());
}
......@@ -8,7 +8,7 @@ pub fn variables_function() {
let mut y = 6;
println!("The value of y is: {}", y);
y = 7;//可变的变量
y = 7; //可变的变量
println!("The value of y is: {}", y);
//常量,必须指定类型,不可省略
const MAX_POINTS: u32 = 100_000;
......@@ -36,26 +36,22 @@ pub fn try_change_function() {
let mut s = String::from("hello");
change(&mut s);
let mut s = String::from("hello");
let r1 = &mut s;
//let r2 = &mut s;//可变引用只能被出借一次,这里将会编译报错
//println!("{}, {}", r1, r2);
let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1在这里超出范围,因此我们可以毫无问题地进行新引用。
let r2 = &mut s;//正常使用,虽然上面已经用过s
let r2 = &mut s; //正常使用,虽然上面已经用过s
let mut s = String::from("hello");
let r1 = &s; // 没问题,与上面两次mut出借不一样,这里是没有mut,所以对于不可变引用,可以使用多次次,且不可在拥有不可变引用时同时拥有可变引用
let r2 = &s; // 没问题
//let r3 = &mut s; // 有问题,不可变在后面却是可变,不允许,编译报错
//println!("{}, {}, and {}", r1, r2, r3);
let r1 = &s; // 没问题,与上面两次mut出借不一样,这里是没有mut,所以对于不可变引用,可以使用多次次,且不可在拥有不可变引用时同时拥有可变引用
let r2 = &s; // 没问题
//let r3 = &mut s; // 有问题,不可变在后面却是可变,不允许,编译报错
//println!("{}, {}, and {}", r1, r2, r3);
let mut s = String::from("hello");
......@@ -69,7 +65,6 @@ pub fn try_change_function() {
}
pub fn expr_function() {
//赋值需要返回值,rust语句没有返回值,不同于其他语言赋值可以连用
// let x = (let y = 6);
......@@ -82,10 +77,10 @@ pub fn expr_function() {
println!("The value of y is: {}", y);
// String转&str的几种办法:
// 1. s.deref() 手动解引用
// 2. &*s 同上
// 3. s.as_ref()
// 4. &s[..]
// 5. s.borrow() 需要use std::borrow::Borrow
}
\ No newline at end of file
// String转&str的几种办法:
// 1. s.deref() 手动解引用
// 2. &*s 同上
// 3. s.as_ref()
// 4. &s[..]
// 5. s.borrow() 需要use std::borrow::Borrow
}
use core::result;
use std::{fmt, thread};
use std::process::id;
use std::sync::{Arc, mpsc, Mutex};
use std::sync::{mpsc, Arc, Mutex};
use std::{fmt, thread};
///定义线程交互消息
enum Message {
......@@ -39,18 +39,21 @@ impl ThreadPool {
pub fn new(size: usize) -> ThreadPool {
assert!(size > 0, "ThreadPool size cannot less than 0");
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));//Arc共享接收器 Mutex任务互斥
//初始化大小
let receiver = Arc::new(Mutex::new(receiver)); //Arc共享接收器 Mutex任务互斥
//初始化大小
let mut workers = Vec::with_capacity(size);
for id in 0..size {
//创建一些线程并将其存储在向量中
workers.push(Worker::new(id, Arc::clone(&receiver)));//共享receiver
workers.push(Worker::new(id, Arc::clone(&receiver))); //共享receiver
}
ThreadPool { workers, sender }
}
//参考thread::spawn对其参数的限制
pub fn execute<F>(&self, f: F) where F: FnOnce() + Send + 'static {
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
self.sender.send(Message::NewJob(Box::new(f))).unwrap();
}
}
......@@ -66,8 +69,9 @@ impl Drop for ThreadPool {
println!("Shutting down all workers.");
for worker in &mut self.workers {
println!("Shutting down worker {}", worker.id);
if let Some(thread) = worker.thread.take() {//take出工作线程并置为None
thread.join().unwrap();//等待主线程的
if let Some(thread) = worker.thread.take() {
//take出工作线程并置为None
thread.join().unwrap(); //等待主线程的
}
}
}
......@@ -98,6 +102,9 @@ impl Worker {
}
}
});
Worker { id, thread: Some(thread) }
Worker {
id,
thread: Some(thread),
}
}
}
use std::{fs, thread};
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::time::Duration;
use std::{fs, thread};
use lib::ThreadPool;
......@@ -37,4 +37,4 @@ fn handle_connection(mut stream: TcpStream) {
let response = format!("{}{}", status_line, contents);
stream.write(response.as_bytes()).unwrap();
stream.flush().unwrap();
}
\ No newline at end of file
}
......@@ -7,124 +7,122 @@ Leetcode Rust 实现
无注明,默认是LeetCode系列
以下按照Solution.rs源码中的行号往下递增
* [面试题 22 链表中倒数第k个节点](src/interview_22.rs)
* [面试题 22 链表中倒数第k个节点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L153)
* [1351 统计有序矩阵中的负数](src/leetcode_1351.rs)
* [1351 统计有序矩阵中的负数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L189)
* [面试题 02.02 返回倒数第 k 个节点值](src/interview_02_02.rs)
* [面试题 02.02 返回倒数第 k 个节点值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L95)
* [面试题 55 - I 二叉树的深度](src/interview_55_1.rs)
* [面试题 55 - I 二叉树的深度](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L207)
* [面试题 04.02 最小高度树](src/interview_04_02.rs)
* [面试题 04.02 最小高度树](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L229)
* [1281 整数的各位积和之差](src/leetcode_1281.rs)
* [1281 整数的各位积和之差](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L255)
* [面试题 58 - II 左旋转字符串](src/interview_58_2.rs)
* [面试题 58 - II 左旋转字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L276)
* [1365 有多少小于当前数字的数字](src/leetcode_1365.rs)
* [1365 有多少小于当前数字的数字](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L292)
* [1342 将数字变成 0 的操作次数](src/leetcode_1342.rs)
* [1342 将数字变成 0 的操作次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L316)
* [1313 解压缩编码列表](src/leetcode_1313.rs)
* [1313 解压缩编码列表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L338)
* [面试题 17 打印从1到最大的n位数](src/interview_17.rs)
* [面试题 17 打印从1到最大的n位数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L364)
* [面试题 05 替换空格](src/interview_05.rs)
* [面试题 05 替换空格](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L429)
* [1221 分割平衡字符串](src/leetcode_1221.rs)
* [1221 分割平衡字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L443)
* [面试题 06 从尾到头打印链表](src/interview_06.rs)
* [面试题 06 从尾到头打印链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L481)
* [938 二叉搜索树的范围和](src/leetcode_938.rs)
* [938 二叉搜索树的范围和](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L505)
* [1021 删除最外层的括号](src/leetcode_1021.rs)
* [1021 删除最外层的括号](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L557)
* [面试题 24 反转链表](src/interview_24.rs)
* [面试题 24 反转链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L605)
* [1252 奇数值单元格的数目](src/leetcode_1252.rs)
* [1252 奇数值单元格的数目](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L634)
* [1323 6 和 9 组成的最大数字](src/leetcode_1323.rs)
* [1323 6 和 9 组成的最大数字](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L664)
* [617 合并二叉树](src/leetcode_617.rs)
* [617 合并二叉树](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L677)
* [461 汉明距离](src/leetcode_461.rs)
* [461 汉明距离](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L729)
* [709 转换成小写字母](src/leetcode_709.rs)
* [709 转换成小写字母](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L338)
* [1304 和为零的N个唯一整数](src/leetcode_1304.rs)
* [1304 和为零的N个唯一整数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L751)
* [804 唯一摩尔斯密码词](src/leetcode_804.rs)
* [804 唯一摩尔斯密码词](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L810)
* [832 翻转图像](src/leetcode_832.rs)
* [832 翻转图像](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L835)
* [面试题 25 合并两个排序的链表](src/interview_25.rs)
* [面试题 25 合并两个排序的链表](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L864)
* [1370 上升下降字符串](src/leetcode_1370.rs)
* [1370 上升下降字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L931)
* [面试题 03.04 化栈为队](src/interview_03_04.rs)
* [面试题 03.04 化栈为队](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L962)
* [1051 高度检查器](src/leetcode_1051.rs)
* [1051 高度检查器](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1023)
* [728 自除数](src/leetcode_728.rs)
* [728 自除数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L045)
* [面试题 01.01 判定字符是否唯一](src/interview_01_01.rs)
* [面试题 01.01 判定字符是否唯一](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1074)
* [1385 两个数组间的距离值](src/leetcode_1385.rs)
* [1385 两个数组间的距离值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1115)
* [面试题 54 二叉搜索树的第k大节点](src/interview_54.rs)
* [面试题 54 二叉搜索树的第k大节点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1141)
* [面试题 09 用两个栈实现队列](src/interview_09.rs)
* [面试题 09 用两个栈实现队列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1174)
* [面试题 16.07 最大数值](src/interview_16_07.rs)
* [面试题 16.07 最大数值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1218)
* [977 有序数组的平方](src/leetcode_977.rs)
* [977 有序数组的平方](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1265)
* [1380 矩阵中的幸运数](src/leetcode_1380.rs)
* [1380 矩阵中的幸运数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1301)
* [933 最近的请求次数](src/leetcode_933.rs)
* [933 最近的请求次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1336)
* [561 数组拆分 I](src/leetcode_561.rs)
* [561 数组拆分 I](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1374)
* [1374 生成每种字符都是奇数个的字符串](src/leetcode_1374.rs)
* [1374 生成每种字符都是奇数个的字符串](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1422)
* [1403 非递增顺序的最小子序列](src/leetcode_1403.rs)
* [1403 非递增顺序的最小子序列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1445)
* [557 反转字符串中的单词 III](src/leetcode_557.rs)
* [557 反转字符串中的单词 III](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1469)
* [999 可以被一步捕获的棋子数](src/leetcode_999.rs)
* [999 可以被一步捕获的棋子数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1487)
* [292 Nim 游戏](src/leetcode_292.rs)
* [292 Nim 游戏](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1537)
* [1160 拼写单词](src/leetcode_1160.rs)
* [1160 拼写单词](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1547)
* [1413 逐步求和得到正数的最小值](src/leetcode_1413.rs)
* [1413 逐步求和得到正数的最小值](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1582)
* [面试题 32 - II. 从上到下打印二叉树 II](src/interview_32_2.rs)
* [面试题 32 - II. 从上到下打印二叉树 II](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1604)
* [944 删列造序](src/leetcode_944.rs)
* [944 删列造序](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1663)
* [9 回文数](src/leetcode_9.rs)
* [9 回文数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1689)
* [13 罗马数字转整数](src/leetcode_13.rs)
* [13 罗马数字转整数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1730)
* [876 链表的中间结点](src/leetcode_876.rs)
* [876 链表的中间结点](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1811)
* [500 键盘行](src/leetcode_500.rs)
* [500 键盘行](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1836)
* [14 长公共前缀](src/leetcode_14.rs)
* [14 长公共前缀](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1856)
* [20 有效的括号](src/leetcode_20.rs)
* [20 有效的括号](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1952)
* [35 搜索插入位置](src/leetcode_35.rs)
* [35 搜索插入位置](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L1982)
* [905 按奇偶排序数组](src/leetcode_905.rs)
* [905 按奇偶排序数组](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2000)
* [1207 独一无二的出现次数](src/leetcode_1207.rs)
* [1207 独一无二的出现次数](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2014)
* [38 外观数列](src/leetcode_38.rs)
* [38 外观数列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2036)
* [58 最后一个单词的长度](src/leetcode_58.rs)
* [58 最后一个单词的长度](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2080)
* [665 非递减数列](https://github.com/jxnu-liguobin/cs-summary-reflection/blob/master/rust-leetcode/src/Solution.rs#L2093)
\ No newline at end of file
* [665 非递减数列](src/leetcode_665.rs)
\ No newline at end of file
use crate::pre_structs::Solution;
///判定字符是否唯一
impl Solution {
pub fn is_unique(astr: String) -> bool {
let cs = astr.chars();
//题目没有说明,但这样AC了,假定只有大小写字母
let mut count = vec![0; ('z' as i32 as usize) + 1]; //123
for c in cs {
count[(c as i32) as usize] += 1;
}
for &c in count.iter() {
if c > 1 {
return false;
}
}
true
}
//位运算
pub fn is_unique2(astr: String) -> bool {
let cs = astr.chars();
let mut mark = 0;
let mut mark_bit = 0;
for c in cs {
mark_bit = c as i32 - ('a' as i32);
if (mark & (1 << mark_bit)) != 0 {
return false;
} else {
mark |= 1 << mark_bit
}
}
true
}
}
use std::borrow::Borrow;
use std::collections::VecDeque;
use crate::pre_structs::{ListNode, Solution};
///返回倒数第 k 个节点
impl Solution {
pub fn kth_to_last(head: Option<Box<ListNode>>, k: i32) -> i32 {
let mut nodes = head;
let mut qs = VecDeque::new();
loop {
if let Some(node) = nodes.borrow() {
qs.push_back(node.val);
nodes = node.next.clone();
} else {
break;
}
}
let i = qs.len() - k as usize;
let ret = qs.get(i);
*ret.unwrap()
}
//倒数第k个,位置就是len-k。即快指针先走k步,然后2个指针同时走,快指针到达尾时,慢指针的位置就是第len-k个元素。此时快指针刚好走完一圈
pub fn kth_to_last2(head: Option<Box<ListNode>>, k: i32) -> i32 {
let mut i = k;
let mut fast = head.as_ref(); //clone也可以,但没有必要,不能copy,没有实现Copy
let mut slow = head.as_ref();
while i > 0 {
if let Some(node) = fast.borrow() {
fast = node.next.as_ref();
i -= 1;
} else {
break;
}
}
while fast != None {
if let Some(node) = fast.borrow() {
fast = node.next.as_ref();
if let Some(node) = slow.borrow() {
slow = node.next.as_ref();
}
}
}
slow.unwrap().val
}
}
use std::collections::VecDeque;
///化栈为队
struct MyQueue {
stack1: VecDeque<Option<i32>>,
stack2: VecDeque<Option<i32>>,
}
impl MyQueue {
/** Initialize your data structure here. */
fn new() -> Self {
MyQueue {
stack1: VecDeque::new(),
stack2: VecDeque::new(),
}
}
/** Push element x to the back of queue. */
fn push(&mut self, x: i32) {
self.stack1.push_back(Some(x))
}
/** Removes the element from in front of queue and returns that element. */
fn pop(&mut self) -> i32 {
return MyQueue::peek_pop(self, true);
}
fn peek_pop(queue: &mut MyQueue, flag: bool) -> i32 {
if queue.stack2.is_empty() {
while !queue.stack1.is_empty() {
queue.stack2.push_back(queue.stack1.pop_back().unwrap());
}
}
let ret = if flag {
queue.stack2.pop_back().unwrap()
} else {
queue.stack2.back().unwrap().clone()
};
ret.unwrap()
}
/** Get the front element. */
fn peek(&mut self) -> i32 {
return MyQueue::peek_pop(self, false);
}
/** Returns whether the queue is empty. */
fn empty(&mut self) -> bool {
self.stack1.is_empty() && self.stack2.is_empty()
}
}
use std::cell::RefCell;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///最小高度树
impl Solution {
pub fn sorted_array_to_bst(nums: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
fn buildTree(nums: &Vec<i32>, l: i32, r: i32) -> Option<Rc<RefCell<TreeNode>>> {
if l > r {
return None;
}
if l == r {
return Some(Rc::new(RefCell::new(TreeNode::new(nums[l as usize]))));
}
let mid = l + (r - l) / 2;
let mut root = TreeNode::new(nums[mid as usize]);
root.left = buildTree(nums, l, mid - 1);
root.right = buildTree(nums, mid + 1, r);
return Some(Rc::new(RefCell::new(root)));
}
return buildTree(&nums, 0, (nums.len() - 1) as i32);
}
}
use crate::pre_structs::Solution;
///替换空格
impl Solution {
pub fn replace_space(s: String) -> String {
let mut str = s;
str.replace(" ", "%20")
}
}
use crate::pre_structs::{ListNode, Solution};
///从尾到头打印链表
impl Solution {
pub fn reverse_print(head: Option<Box<ListNode>>) -> Vec<i32> {
let mut ret = Vec::<i32>::new();
let mut node = head.as_ref();
loop {
if let Some(root) = node {
ret.push(root.val);
node = root.next.as_ref();
} else {
break;
}
}
ret.reverse();
ret
}
}
use std::collections::VecDeque;
///用两个栈实现队列
struct CQueue {
stack1: VecDeque<Option<i32>>,
stack2: VecDeque<Option<i32>>,
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl CQueue {
fn new() -> Self {
CQueue {
stack1: VecDeque::new(),
stack2: VecDeque::new(),
}
}
fn append_tail(&mut self, value: i32) {
self.stack1.push_back(Some(value))
}
fn delete_head(&mut self) -> i32 {
if self.stack2.is_empty() {
while !self.stack1.is_empty() {
self.stack2.push_back(self.stack1.pop_back().unwrap());
}
}
let e = self.stack2.pop_back();
if e.is_none() {
-1
} else {
e.unwrap().unwrap()
}
}
}
use crate::pre_structs::Solution;
///最大数值
impl Solution {
//不能使用if-else 比较运算符
//max(a, b) = ((a + b) + abs(a - b)) / 2。
pub fn maximum(a: i32, b: i32) -> i32 {
let mut a = a as i64;
let mut b = b as i64;
b = a - b;
a -= b & (b >> 32);
a as i32
}
}
use crate::pre_structs::Solution;
///打印从1到最大的n位数
impl Solution {
//8ms
pub fn print_numbers(n: i32) -> Vec<i32> {
let mut max_num = String::new();
for i in 1..=n {
max_num.push('9')
}
let mut ret = Vec::new();
for i in 1..=max_num.parse::<i32>().unwrap() {
ret.push(i);
}
ret
}
//8ms
pub fn print_numbers2(n: i32) -> Vec<i32> {
let mut ret = Vec::new();
let x: i32 = 10;
for i in 1..x.pow(n as u32) {
ret.push(i);
}
ret
}
//20ms
pub fn print_numbers3(n: i32) -> Vec<i32> {
//快速幂
fn pow(mut base: i32, mut index: i32) -> i32 {
let mut ret = 1;
while index > 0 {
if index & 1 == 1 {
ret *= base;
}
index /= 2;
base *= base;
}
ret
}
let mut ret = Vec::new();
for i in 1..pow(10, n) {
ret.push(i);
}
ret
}
}
use std::borrow::Borrow;
use crate::pre_structs::{ListNode, Solution};
///链表中倒数第k个节点
impl Solution {
pub fn get_kth_from_end(head: Option<Box<ListNode>>, k: i32) -> Option<Box<ListNode>> {
let mut i = k;
let mut fast = head.as_ref();
let mut slow = head.as_ref();
while i > 0 {
if let Some(node) = fast.borrow() {
fast = node.next.as_ref();
i -= 1;
}
}
while fast != None {
if let Some(node) = fast.borrow() {
fast = node.next.as_ref();
if let Some(node) = slow.borrow() {
slow = node.next.as_ref();
}
}
}
Some(slow.unwrap().clone())
}
}
use crate::pre_structs::{ListNode, Solution};
///反转链表 leetcode 206
impl Solution {
pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
let mut pre = None;
let mut tmp = head;
loop {
//每次让head指向的节点指向pre指向的节点
if let Some(mut head) = tmp {
tmp = head.next;
head.next = pre;
pre = Some(head);
} else {
break;
}
}
pre
}
}
use crate::pre_structs::{ListNode, Solution};
///合并两个排序的链表
impl Solution {
pub fn merge_two_lists(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
let mut result_head: Option<Box<ListNode>> = Some(Box::new(ListNode {
val: -1,
next: None,
}));
let mut cur = &mut result_head;
let mut l1 = l1;
let mut l2 = l2;
let mut next = true;
while l1.is_some() || l2.is_some() {
//take去除值,并保留为None
match (l1.take(), l2.take()) {
(Some(_l1), None) => {
//可变引用
if let Some(ref mut _cur) = cur {
_cur.next = Some(_l1);
}
}
(None, Some(_l2)) => {
if let Some(ref mut _cur) = cur {
_cur.next = Some(_l2);
}
}
(Some(mut _l1), Some(mut _l2)) => {
if &_l1.val < &_l2.val {
let _next = _l1.next.take();
if let Some(ref mut _cur) = cur {
//将l1拼接到cur后面
_cur.next = Some(_l1);
//移动cur本身
cur = &mut _cur.next;
}
//移动链表l1,并将l2恢复
l1 = _next;
l2 = Some(_l2);
} else {
let _next = _l2.next.take();
if let Some(ref mut _cur) = cur {
_cur.next = Some(_l2);
cur = &mut _cur.next;
}
l2 = _next;
l1 = Some(_l1);
}
}
(None, None) => {}
}
}
return result_head.unwrap().next;
}
}
use std::borrow::{Borrow, BorrowMut};
use std::cell::RefCell;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///二叉树的镜像
impl Solution {
pub fn mirror_tree(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> {
fn mirror(root: &mut Option<Rc<RefCell<TreeNode>>>) {
if let Some(node) = root {
let mut n = node.borrow_mut();
unsafe {
//FUCK YOU
let lt = std::mem::replace(&mut (*n.as_ptr()).left, None);
let rt = std::mem::replace(&mut (*n.as_ptr()).right, lt);
std::mem::replace(&mut (*n.as_ptr()).left, rt);
mirror(&mut (*n.as_ptr()).right);
mirror(&mut (*n.as_ptr()).left);
}
}
}
let mut root = root;
mirror(&mut root);
root
}
}
use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///从上到下打印二叉树 II
impl Solution {
//leetcode 102
pub fn level_order(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<Vec<i32>> {
let mut ret = Vec::new();
let mut nodes = VecDeque::new();
let mut row = Vec::new();
let mut flag = root.clone();
nodes.push_back(root.clone());
while !nodes.is_empty() {
let tmp = nodes.pop_front();
if let Some(node) = tmp {
if let Some(n) = node {
row.push(n.try_borrow().unwrap().val);
if n.try_borrow().unwrap().left.is_some() {
nodes.push_back(n.try_borrow().unwrap().left.clone());
}
if n.try_borrow().unwrap().right.is_some() {
nodes.push_back(n.try_borrow().unwrap().right.clone());
}
if let Some(f) = flag.borrow() {
if f.as_ptr() == n.as_ptr() {
//直接back导致as_ptr不等
let tail = nodes.pop_back();
if tail.is_some() {
flag = tail.clone().unwrap();
nodes.push_back(tail.unwrap());
}
ret.push(row);
row = Vec::new();
}
}
}
}
}
ret
}
}
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///二叉搜索树的第k大节点
impl Solution {
pub fn kth_largest(root: Option<Rc<RefCell<TreeNode>>>, k: i32) -> i32 {
let mut ret = Vec::new();
let mut nodes = VecDeque::new();
let mut cur = root.clone();
while cur.is_some() || !nodes.is_empty() {
while let Some(c) = cur {
nodes.push_back(Some(c.clone()));
cur = c.try_borrow().unwrap().left.clone();
}
if let Some(n) = nodes.pop_back().unwrap() {
ret.push(n.try_borrow().unwrap().val);
cur = n.try_borrow().unwrap().right.clone();
}
}
for e in ret.iter() {
println!("{}", e);
}
ret[(ret.len() - k as usize)]
}
}
use std::cell::RefCell;
use std::cmp::max;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///二叉树的深度 = leetcode 104
impl Solution {
pub fn max_depth(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
fn get_depth(root: &Option<Rc<RefCell<TreeNode>>>) -> i32 {
if let Some(root) = root {
let node = root.try_borrow().unwrap();
return max(get_depth(&node.left), get_depth(&node.right)) + 1;
} else {
return 0;
}
}
get_depth(&root)
}
}
use crate::pre_structs::Solution;
///左旋转字符串
impl Solution {
pub fn reverse_left_words(s: String, n: i32) -> String {
let mut s1 = String::from(&s[0..n as usize]);
let s2 = &s[n as usize..s.len()];
s1.insert_str(0, s2);
s1.to_owned()
}
}
use std::collections::VecDeque;
use crate::pre_structs::Solution;
///删除最外层的括号
impl Solution {
pub fn remove_outer_parentheses(s: String) -> String {
let mut ret_str = String::new();
let mut le = 0;
for c in s.chars() {
if c == ')' {
le -= 1
}
if le >= 1 {
ret_str.push(c)
}
if c == '(' {
le += 1
}
}
ret_str
}
pub fn remove_outer_parentheses2(s: String) -> String {
let mut stack = VecDeque::new();
let mut ret_str = String::new();
for c in s.chars() {
//括号匹配,忽略最左边和最右边的括号
if c == '(' {
stack.push_back(c);
if stack.len() > 1 {
ret_str.push(c);
}
} else {
stack.pop_back();
if stack.len() != 0 {
ret_str.push(c);
}
}
}
ret_str
}
}
use crate::pre_structs::Solution;
///高度检查器
impl Solution {
pub fn height_checker(heights: Vec<i32>) -> i32 {
//排序后与原数组的差异个数
let mut c_heights = heights.clone();
let mut ret = 0;
c_heights.sort();
for i in 0..heights.len() {
if c_heights[i as usize] != heights[i as usize] {
ret += 1;
}
}
ret
}
}
use std::cell::RefCell;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///将有序数组转换为二叉搜索树
impl Solution {
//与最小高度树 interview_04_02 一样
pub fn sorted_array_to_bst2(nums: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
fn buildTree(nums: &Vec<i32>, l: i32, r: i32) -> Option<Rc<RefCell<TreeNode>>> {
if l > r {
return None;
}
let mid = l + (r - l) / 2;
let mut root = TreeNode::new(nums[mid as usize]);
root.left = buildTree(nums, l, mid - 1);
root.right = buildTree(nums, mid + 1, r);
return Some(Rc::new(RefCell::new(root)));
}
buildTree(&nums, 0, nums.len() as i32)
}
}
use crate::pre_structs::Solution;
///拼写单词
impl Solution {
pub fn count_characters(words: Vec<String>, chars: String) -> i32 {
let mut char_count = vec![0; 'z' as usize + 1];
for c in chars.chars() {
char_count[c as usize] += 1;
}
let mut ret = 0;
for word in words.iter() {
let mut word_count = vec![0; 'z' as usize + 1];
for c in word.chars() {
word_count[c as usize] += 1;
}
let mut flg = true;
if word
.chars()
.map(|tc| -> bool { char_count[tc as usize] < word_count[tc as usize] })
.find(|&x| x == true)
.is_some()
{
flg = false;
}
if flg {
ret += word.len()
}
}
ret as i32
}
}
use std::collections::{HashMap, HashSet};
use crate::pre_structs::Solution;
///独一无二的出现次数
impl Solution {
pub fn unique_occurrences(arr: Vec<i32>) -> bool {
let mut map = HashMap::new();
for num in arr.iter() {
let n = if map.contains_key(num) {
map.get(num).unwrap()
} else {
&0
};
if map.contains_key(num) {
map.insert(num, *n + 1);
} else {
map.insert(num, 1);
}
}
let set: HashSet<i32> = map.values().cloned().collect();
set.len() == map.len()
}
}
#[cfg(test)]
mod test {
use crate::pre_structs::Solution;
#[test]
fn unique_occurrences() {}
}
use crate::pre_structs::Solution;
///分割平衡字符串
impl Solution {
pub fn balanced_string_split(s: String) -> i32 {
let mut l = 0;
let mut ret = 0;
for c in s.chars() {
if c == 'L' {
l += 1;
}
if c == 'R' {
l -= 1;
}
if l == 0 {
ret += 1;
}
}
ret
}
//函数式
pub fn balanced_string_split2(s: String) -> i32 {
s.chars()
.scan(0, |acc, e| {
*acc = if let 'R' = e { (*acc + 1) } else { (*acc - 1) };
Some(*acc)
})
.filter(|&e| e == 0)
.count() as i32
}
}
use crate::pre_structs::Solution;
///奇数值单元格的数目
impl Solution {
pub fn odd_cells(n: i32, m: i32, indices: Vec<Vec<i32>>) -> i32 {
let mut arr = vec![vec![0; m as usize]; n as usize];
let mut res = 0;
for row in indices {
for i in 0..n {
arr[i as usize][row[1] as usize] += 1;
}
for j in 0..m {
arr[row[0] as usize][j as usize] += 1;
}
}
for i in 0..n {
for j in 0..m {
if arr[i as usize][j as usize] & 1 == 1 {
res += 1;
}
}
}
res
}
}
use crate::pre_structs::Solution;
///整数的各位积和之差
impl Solution {
pub fn subtract_product_and_sum(n: i32) -> i32 {
let mut num = n;
let mut muti = 1;
let mut sum = 0;
while num != 0 {
let mut tmp = num % 10;
muti *= tmp;
sum += tmp;
num /= 10;
}
muti - sum
}
}
use std::collections::HashMap;
use std::ops::Index;
use crate::pre_structs::Solution;
///罗马数字转整数
impl Solution {
pub fn roman_to_int(s: String) -> i32 {
let mut maps = HashMap::new();
let chs = vec!["I", "V", "X", "L", "C", "D", "M"];
let n = vec![1, 5, 10, 50, 100, 500, 1000];
let mut ret = 0;
let right = s.len() - 1;
n.iter().enumerate().for_each(|(x, &y)| {
maps.insert(chs[x], y);
});
for i in 0..right {
//字不是顺序的,但是数字列表是顺序的
if maps[s.index(i..=i)] >= maps[s.index(i + 1..=i + 1)] {
ret += maps[s.index(i..=i)];
} else {
ret -= maps[s.index(i..=i)];
}
}
ret += maps[s.index(right..=right)];
ret
}
//Legend Lee
pub fn roman_to_int2(s: String) -> i32 {
fn roman_to_int_char(c: char) -> Option<i32> {
match c {
'I' => Some(1),
'V' => Some(5),
'X' => Some(10),
'L' => Some(50),
'C' => Some(100),
'D' => Some(500),
'M' => Some(1000),
_ => None,
}
}
let mut v = 0i32;
if s.is_empty() {
return 0;
}
s.chars()
.zip(s.chars().skip(1))
.for_each(|(first, second)| {
let a = roman_to_int_char(first).unwrap();
let b = roman_to_int_char(second).unwrap();
v += (if a < b { -1 * a } else { a });
});
v += roman_to_int_char(s.chars().last().unwrap()).unwrap();
v
}
//闲杂织造
pub fn roman_to_int3(s: String) -> i32 {
let tr = vec![
('I', 1),
('V', 5),
('X', 10),
('L', 50),
('C', 100),
('D', 500),
('M', 1000),
];
let mut hash: HashMap<char, i32> = tr.iter().cloned().collect();
let chars: Vec<char> = s.chars().collect();
let mut ans = 0;
let n = chars.len();
for i in 0..n - 1 {
let cc = hash[&chars[i]];
let nc = hash[&chars[i + 1]];
if cc < nc {
ans -= cc;
} else {
ans += cc;
}
}
ans + hash[&chars[n - 1]]
}
}
use crate::pre_structs::Solution;
///和为零的N个唯一整数
impl Solution {
//双指针
pub fn sum_zero(n: i32) -> Vec<i32> {
let mut ret = vec![0; n as usize];
let mut i = 0usize;
let mut j = (n - 1) as usize;
let mut c = 1;
loop {
if i >= j {
break;
}
ret[i] = c;
ret[j] = -c;
i += 1;
j -= 1;
c += 1;
}
ret
}
pub fn sum_zero2(n: i32) -> Vec<i32> {
let mut ret = vec![0; n as usize];
let mut sum = 0;
let mut j = 0;
for i in 0..=n - 2 {
ret[j] = i;
j += 1;
sum += i;
}
ret[(n - 1) as usize] = -sum;
ret
}
}
use crate::pre_structs::Solution;
///解压缩编码列表
impl Solution {
pub fn decompress_rl_elist(nums: Vec<i32>) -> Vec<i32> {
let mut rets = Vec::new();
for (index, e) in nums.iter().enumerate() {
if index & 1 == 0 {
let mut freq = nums[index];
let value = nums[index + 1];
while freq != 0 {
rets.push(value);
freq -= 1;
}
}
}
rets
}
}
use crate::pre_structs::Solution;
///6 和 9 组成的最大数字
impl Solution {
pub fn maximum69_number(num: i32) -> i32 {
num.to_string().replacen('6', "9", 1).parse().unwrap()
}
}
use crate::pre_structs::Solution;
///将数字变成 0 的操作次数
impl Solution {
pub fn number_of_steps(num: i32) -> i32 {
let mut n = num;
let mut i = 0;
while n != 0 {
if n & 1 == 0 {
n /= 2;
} else {
n -= 1;
}
i += 1;
}
i
}
}
use crate::pre_structs::Solution;
///统计有序矩阵中的负数
impl Solution {
//应该将矩阵是排序的考虑进去,从右下角或左下角使用标记
pub fn count_negatives(grid: Vec<Vec<i32>>) -> i32 {
let mut count: i32 = 0;
for r in grid.iter() {
count += r.iter().filter(|&&x| x < 0).count() as i32
}
return count;
}
}
use crate::pre_structs::Solution;
///有多少小于当前数字的数字
impl Solution {
pub fn smaller_numbers_than_current(nums: Vec<i32>) -> Vec<i32> {
let mut ret = Vec::with_capacity(nums.len());
for i in 0..nums.len() {
let mut count = 0;
for j in 0..nums.len() {
if nums[i] > nums[j] {
count += 1;
}
}
ret.push(count);
}
ret
}
}
use crate::pre_structs::Solution;
///上升下降字符串
impl Solution {
pub fn sort_string(s: String) -> String {
let mut ret = String::new();
let mut v = vec![0; 26];
for c in s.chars() {
v[c as usize - 97] += 1;
}
while ret.len() < s.len() {
for n in 0..26u8 {
if v[n as usize] > 0 {
ret.push((n + 97) as char);
v[n as usize] -= 1;
}
}
for n in (0..=25u8).rev() {
if v[n as usize] > 0 {
ret.push((n + 97) as char);
v[n as usize] -= 1;
}
}
}
ret
}
}
use crate::pre_structs::Solution;
///生成每种字符都是奇数个的字符串
impl Solution {
//偷鸡
pub fn generate_the_string(n: i32) -> String {
let mut ret = vec![];
if n & 1 == 0 {
ret = vec!['a'; (n - 1) as usize];
ret.push('b');
} else {
ret = vec!['a'; n as usize];
}
let mut rs = String::new();
ret.iter().for_each(|&c| rs.push(c));
rs
}
}
use std::cmp::max;
use std::cmp::min;
use crate::pre_structs::Solution;
///矩阵中的幸运数
impl Solution {
//min数组存放每行最小值;man数组存放每列最大值;
//得到每一行的最小值和每一列的最大值。(行或列上的最大最小值)
//然后比较第i行最小值和第j列最大值是否为同一个数,即min[i] == max[j]
pub fn lucky_numbers(matrix: Vec<Vec<i32>>) -> Vec<i32> {
let m = matrix.len();
let n = matrix[0].len();
let mut min_t = vec![i32::max_value(); m];
let mut max_t = vec![i32::min_value(); n];
for i in 0..m {
for j in 0..n {
min_t[i] = min(min_t[i], matrix[i][j]);
max_t[j] = max(max_t[j], matrix[i][j]);
}
}
let mut result = Vec::new();
for i in 0..m {
for j in 0..n {
if min_t[i] == max_t[j] {
result.push(min_t[i]);
}
}
}
result
}
}
use crate::pre_structs::Solution;
///两个数组间的距离值
impl Solution {
//暴力解
pub fn find_the_distance_value(arr1: Vec<i32>, arr2: Vec<i32>, d: i32) -> i32 {
let mut c = 0;
let ret = arr1.iter().for_each(|&x| {
let mut flag = false;
arr2.iter().for_each(|&y| {
if !flag && (x - y).abs() > d {
} else {
flag = true;
}
});
if !flag {
c += 1;
}
});
c
}
}
use crate::pre_structs::Solution;
///最长公共前缀
impl Solution {
//0 ms, 2.1 MB
pub fn longest_common_prefix(strs: Vec<String>) -> String {
//选出最小的字符串w,使用w的所有子串去匹配strs中的单词
let mut min_word: &String = &"".to_owned();
let mut min_length = usize::max_value();
if strs.is_empty() {
return min_word.clone();
}
let mut result: &str = "";
strs.iter().for_each(|word| {
if min_length > word.len() {
min_length = word.len();
min_word = word;
}
});
while min_length > 0 {
let mut sub_word = &min_word[0..min_length];
let mut is_max = true;
for w in strs.iter() {
if w.starts_with(sub_word) == false {
is_max = false;
break;
}
}
if is_max {
result = sub_word;
break;
}
min_length -= 1;
}
result.to_owned()
}
//0 ms, 2.1 MB
pub fn longest_common_prefix2(strs: Vec<String>) -> String {
let strs = &strs;
let mut result: String = "".to_owned();
if strs.is_empty() {
return result;
}
//选取第一个单词w,对w的长度从大到小进行切片,将切片与所有单词进行匹配
result = strs[0].clone();
for (index, word) in strs.iter().enumerate() {
while !word.starts_with(result.as_str()) {
result = result[0..result.len() - 1].to_owned();
if result.len() == 0 {
return "".to_owned();
}
}
}
result
}
//4 ms, 2.1 MB
pub fn longest_common_prefix3(strs: Vec<String>) -> String {
let strs = &strs;
let mut result: String = "".to_owned();
if strs.is_empty() {
return result;
}
//选取第一个单词w,与其他字符串依次比较对应位置上的字符
let word = &strs[0].clone();
let init_word: Vec<char> = word.chars().collect();
for i in 0..init_word.len() {
let mut c: char = init_word[i];
for j in 1..strs.len() {
let cs: Vec<char> = strs[j].chars().collect();
if i < cs.len() && c != cs[i] || i == cs.len() {
return word[0..i].to_owned();
}
}
}
word.to_owned()
}
}
use crate::pre_structs::Solution;
///非递增顺序的最小子序列
impl Solution {
pub fn min_subsequence(nums: Vec<i32>) -> Vec<i32> {
let mut nums = nums;
nums.sort_by(|a, b| b.cmp(a));
let size = nums.len();
let mut f = 0;
let sum: i32 = nums.iter().sum();
for i in 0..size {
f += nums[i];
if f > sum - f {
return nums[..i + 1].to_vec();
}
}
nums
}
}
use std::cmp::max;
use crate::pre_structs::Solution;
///逐步求和得到正数的最小值
impl Solution {
pub fn min_start_value(nums: Vec<i32>) -> i32 {
let mut start = 1;
let mut min_sum = 0;
for &n in nums.iter() {
min_sum += n;
//累加和的最小值是正数
//min_sum + x >= 1
//x >= 1 - min_sum
//min(x) = 1 - min_sum
start = max(start, 1 - min_sum);
}
start
}
}
use crate::pre_structs::Solution;
///有效的括号
impl Solution {
pub fn is_valid(s: String) -> bool {
let chars: Vec<char> = s.chars().collect();
let mut stack = Vec::<char>::new();
for &c in chars.iter() {
if c == '{' || c == '[' || c == '(' {
stack.push(c);
} else {
if stack.is_empty() {
return false;
}
let c_stack = stack.pop();
if let Some(cStack) = c_stack {
if c == ')' && cStack != '('
|| c == ']' && cStack != '['
|| c == '}' && cStack != '{'
{
return false;
}
}
}
}
stack.is_empty()
}
}
use crate::pre_structs::Solution;
///Nim 游戏
impl Solution {
pub fn can_win_nim(n: i32) -> bool {
if n % 4 == 0 {
false
} else {
true
}
}
}
use crate::pre_structs::Solution;
///搜索插入位置
impl Solution {
pub fn search_insert(nums: Vec<i32>, target: i32) -> i32 {
let mut nums = nums;
//找到知己反回索引,没有找到则返回该元素插入后保持数组仍然有序的索引位置,主要用于有序的数组/向量
let ret = match nums.binary_search(&target) {
Ok(found_index) => found_index,
Err(maybe_insert) => maybe_insert,
};
ret as i32
}
}
#[cfg(test)]
mod test {
use crate::pre_structs::Solution;
#[test]
fn search_insert() {}
}
use crate::pre_structs::Solution;
///外观数列
impl Solution {
//给一个数,这个数是1
//描述上一步的数,这个数是1即一个1,故写作11
//描述上一步的数,这个数是11即两个1,故写作21
//描述上一步的数,这个数是21即一个2一个1,故写作12-11
//描述上一步的数,这个数是1211即一个1一个2两个1,故写作11-12-21
pub fn count_and_say(n: i32) -> String {
if n == 1 {
return "1".to_owned();
}
let pre_str = Solution::count_and_say(n - 1);
let mut curr_str = String::new();
let mut pre_char = None;
let mut pre_char_count = 0;
//当n为2及以上时。因为下一个数列是对上面的解释。所以用三个变量,一个代表数量count ,一个代表前一个数字pre,一个代表后一个数字back
for back_char in pre_str.chars() {
if pre_char == None {
pre_char = Some(back_char);
}
if back_char != pre_char.unwrap() {
//将pre_char_count个pre_char分别存储
curr_str.push_str(&pre_char_count.to_string());
curr_str.push(pre_char.unwrap());
pre_char = Some(back_char);
//不同时,重置个数
pre_char_count = 1;
} else {
//相等时计算字符个数
pre_char_count += 1;
}
}
//最后一位在前面跳出来了,需要追加
if pre_char_count > 0 {
curr_str.push_str(&pre_char_count.to_string());
curr_str.push(pre_char.unwrap());
}
curr_str
}
}
#[cfg(test)]
mod test {
use crate::pre_structs::Solution;
#[test]
fn count_and_say() {}
}
use crate::pre_structs::Solution;
///汉明距离
impl Solution {
pub fn hamming_distance(x: i32, y: i32) -> i32 {
let mut nums = x ^ y;
//二进制中1的个数
let mut c = 0;
while nums != 0 {
if nums & 1 == 1 {
c += 1;
}
nums = nums >> 1;
}
c
}
}
use std::collections::{HashMap, HashSet};
use crate::pre_structs::Solution;
///键盘行
impl Solution {
pub fn find_words(words: Vec<String>) -> Vec<String> {
let map: HashMap<char, i32> = vec![
('Q', 0),
('W', 0),
('E', 0),
('R', 0),
('T', 0),
('Y', 0),
('U', 0),
('I', 0),
('O', 0),
('P', 0),
('A', 1),
('S', 1),
('D', 1),
('F', 1),
('G', 1),
('H', 1),
('J', 1),
('K', 1),
('L', 1),
('Z', 2),
('X', 2),
('C', 2),
('V', 2),
('B', 2),
('N', 2),
('M', 2),
]
.iter()
.cloned()
.collect();
words
.iter()
.filter(|word| {
let chars: Vec<char> = word.chars().collect();
let index: HashSet<i32> = chars
.iter()
.map(|c| -> i32 { map[&c.to_ascii_uppercase()] })
.collect();
index.len() == 1
})
.cloned()
.collect()
}
}
use crate::pre_structs::Solution;
///反转字符串中的单词 III
impl Solution {
pub fn reverse_words(s: String) -> String {
let arr: Vec<&str> = s.split(' ').collect();
let ret: Vec<String> = arr
.iter()
.map(|word| -> String {
let c: String = (*word).chars().rev().collect();
c
})
.collect();
ret.join(" ").to_string()
}
}
use crate::pre_structs::Solution;
///数组拆分 I
impl Solution {
//尽可能保留最大值
pub fn array_pair_sum(nums: Vec<i32>) -> i32 {
let mut nums = nums;
nums.sort();
let mut sum = 0;
let mut i = 0;
while i < nums.len() {
sum += nums[i as usize];
i += 2;
}
sum
}
}
use crate::pre_structs::Solution;
///最后一个单词的长度
impl Solution {
pub fn length_of_last_word(s: String) -> i32 {
let chars: Vec<&str> = s.trim().split(' ').collect();
chars[chars.len() - 1].len() as i32
}
}
#[cfg(test)]
mod test {
use crate::pre_structs::Solution;
#[test]
fn length_of_last_word() {}
}
use std::borrow::{Borrow, BorrowMut};
use std::cell::RefCell;
use std::rc::Rc;
use crate::pre_structs::{Solution, TreeNode};
///合并二叉树
impl Solution {
///author 李广胜
pub fn merge_trees(
t1: Option<Rc<RefCell<TreeNode>>>,
t2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
if t1.is_none() {
return t2;
}
if t2.is_none() {
return t1;
}
let b1: Rc<RefCell<TreeNode>> = t1.unwrap();
let b1: &RefCell<TreeNode> = b1.borrow();
let b2: Rc<RefCell<TreeNode>> = t2.unwrap();
let b2: &RefCell<TreeNode> = b2.borrow();
unsafe {
//直接b2.val编译错误
Some(Rc::new(RefCell::new(TreeNode {
val: (*b1.as_ptr()).val + (*b2.as_ptr()).val,
left: Solution::merge_trees(
(*b1.as_ptr()).left.clone(),
(*b2.as_ptr()).left.clone(),
),
right: Solution::merge_trees(
(*b1.as_ptr()).right.clone(),
(*b2.as_ptr()).right.clone(),
),
})))
}
}
///author 长条人
pub fn merge_trees2(
t1: Option<Rc<RefCell<TreeNode>>>,
t2: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
fn merge(t1: &mut Option<Rc<RefCell<TreeNode>>>, t2: &Option<Rc<RefCell<TreeNode>>>) {
if let Some(mut n1) = t1.as_ref() {
if let Some(n2) = t2 {
let mut n1 = n1.borrow_mut();
let n2: &RefCell<TreeNode> = n2.borrow();
unsafe {
(*n1.as_ptr()).val += (*n2.as_ptr()).val;
merge(&mut (*n1.as_ptr()).left, &(*n2.as_ptr()).left);
merge(&mut (*n1.as_ptr()).right, &(*n2.as_ptr()).right);
}
} else {
}
} else {
*t1 = t2.clone();
}
}
let mut t1 = t1;
merge(&mut t1, &t2);
t1
}
}
use crate::pre_structs::Solution;
///非递减数列
impl Solution {
pub fn check_possibility(nums: Vec<i32>) -> bool {
let mut nums = nums;
let mut cnt = 0;
if nums.len() < 2 {
return true;
}
//将局部调整为最优方案
//当 i 和 i+1 构成逆序时
for i in 0..nums.len() - 1 {
if nums[i] > nums[i + 1] {
if i == 0 || nums[i - 1] <= nums[i + 1] {
//如果 i-1 和 i+1 是升序排列,此时缩小 i 的值
nums[i] = nums[i + 1];
} else if nums[i - 1] > nums[i + 1] {
//如果 i-1 和 i+1 是降序排列,此时增大 i+1 的值
nums[i + 1] = nums[i];
} else {
}
//计算需要改动的次数
cnt += 1;
if cnt > 1 {
return false;
}
}
}
true
}
}
#[cfg(test)]
mod test {
use crate::pre_structs::Solution;
#[test]
fn check_possibility() {}
}
use crate::pre_structs::Solution;
///转换成小写字母
impl Solution {
pub fn to_lower_case(str: String) -> String {
str.chars()
.map(|c| {
//说明是大写,+32
if c < 'a' && c >= 'A' {
(c as u8 + 32 as u8) as char
} else {
c
}
})
.collect()
}
}
use crate::pre_structs::Solution;
///自除数
impl Solution {
pub fn self_dividing_numbers(left: i32, right: i32) -> Vec<i32> {
let mut result = Vec::new();
for num in left..=right {
if helper(num) {
result.push(num)
}
}
fn helper(n: i32) -> bool {
for c in n.to_string().chars() {
if ((c as i32) - 48) == 0 || n % ((c as i32) - 48) != 0 {
return false;
}
}
return true;
}
result
}
}
use std::collections::HashSet;
use crate::pre_structs::Solution;
///唯一摩尔斯密码词
impl Solution {
pub fn unique_morse_representations(words: Vec<String>) -> i32 {
let m = vec![
".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--..",
];
let mut ret = HashSet::new();
for w in words.iter() {
let mut mw = String::new();
for c in w.chars() {
//bad smell
let c = m[(c as u8 - 97) as usize];
mw.push_str(c);
}
ret.insert(mw);
}
ret.len() as i32
}
}
use crate::pre_structs::Solution;
///翻转图像
impl Solution {
pub fn flip_and_invert_image(a: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let ret: Vec<Vec<i32>> = a
.iter()
.map(|mut row| -> Vec<i32> {
let mut new_row: Vec<i32> = row
.iter()
.map(|x| -> i32 {
let new_x = if let 0 = x { 1 } else { 0 };
new_x
})
.collect();
new_row.reverse();
new_row
})
.collect();
ret
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册