这个网站 可以列出某门编程语言的常用语法,也可以对比两种语言的基本语法差别。
在此对比Go和Rust
1. Print Hello World 打印Hello World
1 2 3 4 5 6 7 8 9 package mainimport "fmt" func main () { fmt.Println("Hello World" ) }
1 2 3 4 fn main () { println! ("Hello World" ); }
Rust 输出文字的方式主要有两种:println!() 和 print!() 。这两个”函数”都是向命令行输出字符串的方法,区别仅在于前者会在输出的最后附加输出一个换行符。当用这两个”函数”输出信息的时候,第一个参数是格式字符串,后面是一串可变参数,对应着格式字符串中的”占位符”,这一点与 C 语言/ Go语言 中的 printf 函数很相似。但是,Rust 中格式字符串中的占位符不是”% + 字母”的形式,而是一对 {}。
2. Print Hello 10 times 打印10次Hello World
1 2 3 4 5 6 7 8 9 10 11 package mainimport ( "fmt" ) func main () { for i := 0 ; i < 10 ; i++ { fmt.Println("Hello" ) } }
or
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport ( "fmt" "strings" ) func main () { fmt.Print(strings.Repeat("Hello\n" , 10 )) }
1 2 3 4 5 fn main () { for _ in 0 ..10 { println! ("Hello" ); } }
or
1 2 3 4 fn main () { print! ("{}" , "Hello\n" .repeat (10 )); }
3. Create a procedure
Like a function which doesn’t return any value, thus has only side effects (e.g. Print to standard output)
创建一个方法,没有返回值,打印一些内容
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport "fmt" func finish (name string ) { fmt.Println("My job here is done. Good bye " + name) } func main () { finish("Tony" ) }
1 2 3 4 5 6 7 fn main (){ finish ("Buddy" ) } fn finish (name : &str ) { println! ("My job here is done. Goodbye {}" , name); }
4. Create a function which returns the square of an integer 创建一个函数,返回一个整数的平方
1 2 3 4 func square (x int ) int { return x*x }
1 2 3 4 5 6 7 8 9 10 fn square (x: u32 ) -> u32 { x * x } fn main () { let sq = square (9 ); println! ("{}" , sq); }
5. Create a 2D Point data structure
Declare a container type for two floating-point numbers x and y
声明一个容器类型,有x、y两个浮点数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package mainimport "fmt" type Point struct { x, y float64 } func main () { p1 := Point{} p2 := Point{2.1 , 2.2 } p3 := Point{ y: 3.1 , x: 3.2 , } p4 := &Point{ x: 4.1 , y: 4.2 , } fmt.Println(p1) fmt.Println(p2) fmt.Println(p3) fmt.Println(p4) }
输出
1 2 3 4 5 {0 0 } {2.1 2.2 } {3.2 3.1 } &{4.1 4.2 }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 use std::fmt;struct Point { x: f64 , y: f64 , } impl fmt ::Display for Point { fn fmt (&self , f: &mut fmt::Formatter<'_ >) -> fmt::Result { write! (f, "({}, {})" , self .x, self .y) } } fn main () { let p = Point { x: 2.0 , y: -3.5 }; println! ("{}" , p); }
or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use std::fmt;struct Point (f64 , f64 );impl fmt ::Display for Point { fn fmt (&self , f: &mut fmt::Formatter<'_ >) -> fmt::Result { write! (f, "({}, {})" , self .0 , self .1 ) } } fn main () { let p = Point (2.0 , -3.5 ); println! ("{}" , p); }
6. Iterate over list values
Do something with each item x of an array-like collection items, regardless indexes.
遍历列表的值
1 2 3 4 for _, x := range items { doSomething(x) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "fmt" ) func main () { items := []int {11 , 22 , 33 } for _, x := range items { doSomething(x) } } func doSomething (i int ) { fmt.Println(i) }
输出
1 2 3 4 5 6 7 8 9 10 11 fn main () { let items = vec! [11 , 22 , 33 ]; for x in items { do_something (x); } } fn do_something (n: i64 ) { println! ("Number {}" , n) }
or
1 2 3 4 5 6 7 8 9 fn main () { let items = vec! [11 , 22 , 33 ]; items.into_iter ().for_each(|x| do_something (x)); } fn do_something (n: i64 ) { println! ("Number {}" , n) }
7. Iterate over list indexes and values 遍历列表的索引和值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mainimport "fmt" func main () { items := []string { "oranges" , "apples" , "bananas" , } for i, x := range items { fmt.Printf("Item %d = %v \n" , i, x) } }
输出
1 2 3 Item 0 = oranges Item 1 = apples Item 2 = bananas
1 2 3 4 5 6 fn main () { let items = ["a" , "b" , "c" ]; for (i, x) in items.iter ().enumerate () { println! ("Item {} = {}" , i, x); } }
or
1 2 3 4 5 6 fn main () { let items = ["a" , "b" , "c" ]; items.iter ().enumerate ().for_each(|(i, x)| { println! ("Item {} = {}" , i, x); }); }
8. Initialize a new map (associative array)
Create a new map object x, and provide some (key, value) pairs as initial content.
创建一个新的map,提供一些键值对 作为初始内容
1 2 3 4 5 6 7 8 9 10 package mainimport "fmt" func main () { x := map [string ]int {"one" : 1 , "two" : 2 } fmt.Println(x) }
输出
1 2 3 4 5 6 7 8 9 use std::collections::BTreeMap;fn main () { let mut x = BTreeMap::new (); x.insert ("one" , 1 ); x.insert ("two" , 2 ); println! ("{:?}" , x); }
输出为:
or
1 2 3 4 5 6 7 8 9 10 use std::collections::HashMap;fn main () { let x : HashMap<&str , i32 > = [ ("one" , 1 ), ("two" , 2 ), ].iter ().cloned ().collect (); println! ("{:?}" , x); }
输出为:
分 BTreeMap 和 HashMap,且都需要use进来; 前者有序,后者无序
BTreeMap 和 HashMap 都是 Rust 标准库中的映射(Map)类型,但它们在实现方式和用途上有所不同:
实现方式:
采用 B-树(B-Tree)数据结构实现,每个节点可以存储多个键值对,且按照键的顺序进行排序,因此 `BTreeMap` 的键是有序的。而 `HashMap` 采用哈希表(Hash Table)实现,将键映射到桶(Bucket)中,每个桶存储一个或多个键值对,因此 `HashMap` 的键是无序的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2. 用途: ```BTreeMap` 适用于需要按照键进行排序的场景,例如需要对键进行范围查找(range search)或遍历时。而 `HashMap` 适用于需要快速插入、查找和删除键值对的场景,例如需要频繁地更新数据或进行高速查找时。 在使用时,你可以根据具体的需求和性能要求选择 `BTreeMap` 或 `HashMap`。如果需要对键进行排序或提供范围查找,则应使用 `BTreeMap`;如果需要快速地插入、查找和删除键值对,则应使用 `HashMap`。 需要注意的是,由于 `BTreeMap` 使用 B-树 数据结构,因此在某些情况下可能会比 `HashMap` 更占用内存。此外,由于 `HashMap` 的键是无序的,因此在遍历时不能保证键值对的顺序。 <br> ### 9. <font color="1e6091">Create a Binary Tree data structure</font> > The structure must be recursive because left child and right child are binary trees too. A node has access to children nodes, but not to its parent. *创建一个二叉树* ```go type BinTree struct { Value valueType Left *BinTree Right *BinTree }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package mainimport "fmt" type BinTree struct { Value int Left *BinTree Right *BinTree } func inorder (root *BinTree) { if root == nil { return } inorder(root.Left) fmt.Printf("%d " , root.Value) inorder(root.Right) } func main () { root := &BinTree{1 , nil , nil } root.Left = &BinTree{2 , nil , nil } root.Right = &BinTree{3 , nil , nil } root.Left.Left = &BinTree{4 , nil , nil } root.Left.Right = &BinTree{5 , nil , nil } root.Right.Right = &BinTree{6 , nil , nil } root.Left.Left.Left = &BinTree{7 , nil , nil } inorder(root) }
输出
1 2 3 4 5 6 struct BinTree <T> { value: T, left: Option <Box <BinTree<T>>>, right: Option <Box <BinTree<T>>>, }
10. Shuffle a list
Generate a random permutation of the elements of list x
随机排序一个list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package mainimport ( "fmt" "math/rand" ) func main () { x := []string {"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" } for i := range x { j := rand.Intn(i + 1 ) x[i], x[j] = x[j], x[i] } fmt.Println(x) }
输出
[f e c g h a d b]
or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package mainimport ( "fmt" "math/rand" ) func main () { x := []string {"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" } y := make ([]string , len (x)) perm := rand.Perm(len (x)) for i, v := range perm { y[v] = x[i] } fmt.Println(y) }
输出
[f h c g b a d e]
rand.Perm(x)挺有意思的一个函数,perm应该是permutation的缩写,即置换,排列。
会输出一个从0-(x-1)随机顺序排列的数组,类似洗牌,总数不变,打乱顺序
or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mainimport ( "fmt" "math/rand" ) func main () { x := []string {"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" } rand.Shuffle(len (x), func (i, j int ) { x[i], x[j] = x[j], x[i] }) fmt.Println(x) }
输出
[f a h b c d g e]
or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "fmt" "math/rand" ) func main () { x := []string {"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" } for i := len (x) - 1 ; i > 0 ; i-- { j := rand.Intn(i + 1 ) x[i], x[j] = x[j], x[i] } fmt.Println(x) }
输出
[g d a h e f c b]
1 2 3 4 5 extern crate rand;use rand::{Rng, StdRng};let mut rng = StdRng::new ().unwrap ();rng.shuffle (&mut x);
or
1 2 3 4 5 6 7 8 9 10 11 12 13 use rand::seq::SliceRandom;use rand::thread_rng;fn main () { let mut x = [1 , 2 , 3 , 4 , 5 ]; println! ("Unshuffled: {:?}" , x); let mut rng = thread_rng (); x.shuffle (&mut rng); println! ("Shuffled: {:?}" , x); }
11. Pick a random element from a list 从列表中选择一个随机元素
1 2 3 4 5 6 7 8 9 10 11 12 13 package mainimport ( "fmt" "math/rand" ) var x = []string {"bleen" , "fuligin" , "garrow" , "grue" , "hooloovoo" }func main () { fmt.Println(x[rand.Intn(len (x))]) }
输出
fuligin
or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package mainimport ( "fmt" "math/rand" ) type T string func pickT (x []T) T { return x[rand.Intn(len (x))] } func main () { var list = []T{"bleen" , "fuligin" , "garrow" , "grue" , "hooloovoo" } fmt.Println(pickT(list)) }
输出
fuligin
1 2 3 4 5 6 7 8 9 use rand::{self , Rng};fn main () { let x = vec! [11 , 22 , 33 ]; let choice = x[rand::thread_rng ().gen_range (0 ..x.len ())]; println! ("I picked {}!" , choice); }
or
1 2 3 4 5 6 7 8 9 10 use rand::seq::SliceRandom; fn main () { let x = vec! [11 , 22 , 33 ]; let mut rng = rand::thread_rng (); let choice = x.choose (&mut rng).unwrap (); println! ("I picked {}!" , choice); }
12. Check if list contains a value
Check if list contains a value x. list is an iterable finite container.
检查列表中是否包含一个值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport "fmt" func Contains (list []T, x T) bool { for _, item := range list { if item == x { return true } } return false } type T string func main () { list := []T{"a" , "b" , "c" } fmt.Println(Contains(list, "b" )) fmt.Println(Contains(list, "z" )) }
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 fn main () { let list = [10 , 40 , 30 ]; { let num = 30 ; if list.contains (&num) { println! ("{:?} contains {}" , list, num); } else { println! ("{:?} doesn't contain {}" , list, num); } } { let num = 42 ; if list.contains (&num) { println! ("{:?} contains {}" , list, num); } else { println! ("{:?} doesn't contain {}" , list, num); } } }
or
1 2 3 4 5 6 7 8 9 10 fn main () { let list = [10 , 40 , 30 ]; let x = 30 ; if list.iter ().any (|v| v == &x) { println! ("{:?} contains {}" , list, x); } else { println! ("{:?} doesn't contain {}" , list, x); } }
or
1 2 3 4 5 6 7 8 9 10 fn main () { let list = [10 , 40 , 30 ]; let x = 30 ; if (&list).into_iter ().any (|v| v == &x) { println! ("{:?} contains {}" , list, x); } else { println! ("{:?} doesn't contain {}" , list, x); } }
13. Iterate over map keys and values
Access each key k with its value x from an associative array mymap, and print them
遍历关联数组中的每一对 k-v, 并打印出它们
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mainimport "fmt" func main () { mymap := map [string ]int { "one" : 1 , "two" : 2 , "three" : 3 , "four" : 4 , } for k, x := range mymap { fmt.Println("Key =" , k, ", Value =" , x) } }
输出
1 2 3 4 Key = two , Value = 2 Key = three , Value = 3 Key = four , Value = 4 Key = one , Value = 1
1 2 3 4 5 6 7 8 9 10 11 12 13 use std::collections::BTreeMap;fn main () { let mut mymap = BTreeMap::new (); mymap.insert ("one" , 1 ); mymap.insert ("two" , 2 ); mymap.insert ("three" , 3 ); mymap.insert ("four" , 4 ); for (k, x) in &mymap { println! ("Key={key}, Value={val}" , key = k, val = x); } }
Pick a random number greater than or equals to a, strictly inferior to b. Precondition : a < b.
选出一个随机的浮点数,大于或等于a,严格小于b,且a< b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport ( "fmt" "math/rand" ) func main () { x := pick(-2.0 , 6.5 ) fmt.Println(x) } func pick (a, b float64 ) float64 { return a + (rand.Float64() * (b - a)) }
输出
3.1396124478267664
1 2 3 4 5 6 7 8 extern crate rand;use rand::{thread_rng, Rng};fn main () { let (a, b) = (1.0 , 3.0 ); let c = thread_rng ().gen_range (a..b); println! ("{}" , c); }
Pick a random integer greater than or equals to a, inferior or equals to b. Precondition : a < b.
选出一个随机的整数,大于或等于a,小于或等于b,且a< b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package mainimport ( "fmt" "math/rand" ) func main () { x := pick(3 , 7 ) fmt.Println(x) } func pick (a, b int ) int { return a + rand.Intn(b-a+1 ) }
输出
4
1 2 3 4 5 fn pick (a: i32 , b: i32 ) -> i32 { let between = Range::new (a, b); let mut rng = rand::thread_rng (); between.ind_sample (&mut rng) }
or
1 2 3 4 5 6 7 8 9 10 use rand::distributions::Distribution;use rand::distributions::Uniform;fn main () { let (a, b) = (3 , 5 ); let x = Uniform::new_inclusive (a, b).sample (&mut rand::thread_rng ()); println! ("{}" , x); }
17. Create a Tree data structure
The structure must be recursive. A node may have zero or more children. A node has access to children nodes, but not to its parent.
创建树数据结构, 该结构必须是递归的。一个节点可以有零个或多个子节点,节点可以访问子节点,但不能访问其父节点
1 2 3 4 5 type Tree struct { Key keyType Deco valueType Children []*Tree }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package mainimport "fmt" type Tree struct { Key key Deco value Children []*Tree } type key string type value string func (t *Tree) String() string { str := "(" str += string (t.Deco) if len (t.Children) == 0 { return str + ")" } str += " (" for _, child := range t.Children { str += child.String() } str += "))" return str } func (this *Tree) AddChild(x key, v value) *Tree { child := &Tree{Key: x, Deco: v} this.Children = append (this.Children, child) return child } func main () { tree := &Tree{Key: "Granpa" , Deco: "Abraham" } subtree := tree.AddChild("Dad" , "Homer" ) subtree.AddChild("Kid 1" , "Bart" ) subtree.AddChild("Kid 2" , "Lisa" ) subtree.AddChild("Kid 3" , "Maggie" ) fmt.Println(tree) }
输出
(Abraham ((Homer ((Bart)(Lisa)(Maggie)))))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 use std::vec;struct Node <T> { value: T, children: Vec <Node<T>>, } impl <T> Node<T> { pub fn dfs <F: Fn (&T)>(&self , f: F) { self .dfs_helper (&f); } fn dfs_helper <F: Fn (&T)>(&self , f: &F) { (f)(&self .value); for child in &self .children { child.dfs_helper (f); } } } fn main () { let t : Node<i32 > = Node { children: vec! [ Node { children: vec! [ Node { children: vec! [], value: 14 } ], value: 28 }, Node { children: vec! [], value: 80 } ], value: 50 }; t.dfs (|node| { println! ("{}" , node); }); }
输出:
18. Depth-first traversing of a tree
Call a function f on every node of a tree, in depth-first prefix order
树的深度优先遍历。按照深度优先的前缀顺序,在树的每个节点上调用函数f
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package mainimport . "fmt" func (t *Tree) Dfs(f func (*Tree) ) { if t == nil { return } f(t) for _, child := range t.Children { child.Dfs(f) } } type key string type value string type Tree struct { Key key Deco value Children []*Tree } func (this *Tree) AddChild(x key, v value) { child := &Tree{Key: x, Deco: v} this.Children = append (this.Children, child) } func NodePrint (node *Tree) { Printf("%v (%v)\n" , node.Deco, node.Key) } func main () { tree := &Tree{Key: "Granpa" , Deco: "Abraham" } tree.AddChild("Dad" , "Homer" ) tree.Children[0 ].AddChild("Kid 1" , "Bart" ) tree.Children[0 ].AddChild("Kid 2" , "Lisa" ) tree.Children[0 ].AddChild("Kid 3" , "Maggie" ) tree.Dfs(NodePrint) }
输出
1 2 3 4 5 Abraham (Granpa) Homer (Dad) Bart (Kid 1 ) Lisa (Kid 2 ) Maggie (Kid 3 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 use std::vec;struct Tree <T> { children: Vec <Tree<T>>, value: T } impl <T> Tree<T> { pub fn new (value: T) -> Self { Tree{ children: vec! [], value } } pub fn dfs <F: Fn (&T)>(&self , f: F) { self .dfs_helper (&f); } fn dfs_helper <F: Fn (&T)>(&self , f: &F) { (f)(&self .value); for child in &self .children { child.dfs_helper (f); } } } fn main () { let t : Tree<i32 > = Tree { children: vec! [ Tree { children: vec! [ Tree { children: vec! [], value: 14 } ], value: 28 }, Tree { children: vec! [], value: 80 } ], value: 50 }; t.dfs (|node| { println! ("{}" , node); }); }
输出:
19. Reverse a list
Reverse the order of the elements of list x. This may reverse “in-place” and destroy the original ordering.
反转链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package mainimport "fmt" func main () { s := []int {5 , 2 , 6 , 3 , 1 , 4 } for i, j := 0 , len (s)-1 ; i < j; i, j = i+1 , j-1 { s[i], s[j] = s[j], s[i] } fmt.Println(s) }
输出
[4 1 3 6 2 5]
1 2 3 4 5 fn main () { let x = vec! ["Hello" , "World" ]; let y : Vec <_> = x.iter ().rev ().collect (); println! ("{:?}" , y); }
输出:
or
1 2 3 4 5 fn main () { let mut x = vec! [1 ,2 ,3 ]; x.reverse (); println! ("{:?}" , x); }
输出:
20. Return two values
Implement a function search which looks for item x in a 2D matrix m. Return indices i, j of the matching cell. Think of the most idiomatic way in the language to return the two values at the same time.
实现在2D矩阵m中寻找元素x,返回匹配单元格的索引 i,j
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport "fmt" func search (m [][]int , x int ) (bool , int , int ) { for i := range m { for j, v := range m[i] { if v == x { return true , i, j } } } return false , 0 , 0 } func main () { matrix := [][]int { {1 , 2 , 3 }, {4 , 5 , 6 }, {7 , 8 , 9 }, } for x := 1 ; x <= 11 ; x += 2 { found, i, j := search(matrix, x) if found { fmt.Printf("matrix[%v][%v] == %v \n" , i, j, x) } else { fmt.Printf("Value %v not found. \n" , x) } } }
输出
1 2 3 4 5 6 matrix[0 ][0 ] == 1 matrix[0 ][2 ] == 3 matrix[1 ][1 ] == 5 matrix[2 ][0 ] == 7 matrix[2 ][2 ] == 9 Value 11 not found.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 fn search <T: Eq >(m: &Vec <Vec <T>>, x: &T) -> Option <(usize , usize )> { for (i, row) in m.iter ().enumerate () { for (j, column) in row.iter ().enumerate () { if *column == *x { return Some ((i, j)); } } } None } fn main () { let a = vec! [ vec! [0 , 11 ], vec! [22 , 33 ], vec! [44 , 55 ], ]; let hit = search (&a, &33 ); println! ("{:?}" , hit); }
输出:
原文链接: https://dashen.tech/2021/09/02/Rust-vs-Go-常用语法对比/
版权声明: 转载请注明出处.