Rust vs Go:常用语法对比(7)(1)

简介: Rust vs Go:常用语法对比(7)(1)

121. UDP listen and read

Listen UDP traffic on port p and read 1024 bytes into buffer b.

听端口p上的UDP流量,并将1024字节读入缓冲区b。

import (
    "fmt"
    "net"
    "os"
)
ServerAddr,err := net.ResolveUDPAddr("udp",p)
if err != nil {
  return err
}
ServerConn, err := net.ListenUDP("udp", ServerAddr)
if err != nil {
  return err
}
defer ServerConn.Close()
n,addr,err := ServerConn.ReadFromUDP(b[:1024])
if err != nil {
  return err
}
if n<1024 {
  return fmt.Errorf("Only %d bytes could be read.", n)
}
use std::net::UdpSocket;
let mut b = [0 as u8; 1024];
let sock = UdpSocket::bind(("localhost", p)).unwrap();
sock.recv_from(&mut b).unwrap();

122. Declare enumeration

Create an enumerated type Suit with 4 possible values SPADES, HEARTS, DIAMONDS, CLUBS.

声明枚举值

package main
import (
  "fmt"
)
type Suit int
const (
  Spades Suit = iota
  Hearts
  Diamonds
  Clubs
)
func main() {
  fmt.Printf("Hearts has type %T and value %d", Hearts, Hearts)
}
enum Suit {
    Spades,
    Hearts,
    Diamonds,
    Clubs,
}
fn main() {
    let _x = Suit::Diamonds;
}

123.  Assert condition

Verify that predicate isConsistent returns true, otherwise report assertion violation. Explain if the assertion is executed even in production environment or not.

断言条件

package main
import "fmt"
//
// The code may look fine, but
// obviously we have a bug.
//
func main() {
  salary = 65000
  employees = 120000
  totalPayroll = salary * employees
  if !isConsistent() {
    panic("State consistency violated")
  }
  fmt.Println("Everything fine")
}
var salary int32
var employees int32
var totalPayroll int32
func isConsistent() bool {
  return salary >= 0 &&
    employees >= 0 &&
    totalPayroll >= 0
}
fn main() {
    // i is odd
    let i = 23687;
    let ii = i * i;
    let is_consistent = ii % 2 == 1;
    // i*i must be odd
    assert!(is_consistent);
    println!("Cool.")
}

124.  Binary search for a value in sorted array

Write function binarySearch which returns the index of an element having value x in sorted array a, or -1 if no such element.

排序数组中值的二分搜索法

二分查找

package main
import "fmt"
func binarySearch(a []T, x T) int {
  imin, imax := 0, len(a)-1
  for imin <= imax {
    imid := (imin + imax) / 2
    switch {
    case a[imid] == x:
      return imid
    case a[imid] < x:
      imin = imid + 1
    default:
      imax = imid - 1
    }
  }
  return -1
}
type T int
func main() {
  a := []T{-2, -1, 0, 1, 1, 1, 6, 8, 8, 9, 10}
  for x := T(-5); x <= 15; x++ {
    i := binarySearch(a, x)
    if i == -1 {
      fmt.Println("Value", x, "not found")
    } else {
      fmt.Println("Value", x, "found at index", i)
    }
  }
}

or

package main
import (
  "fmt"
  "sort"
)
func binarySearch(a []int, x int) int {
  i := sort.SearchInts(a, x)
  if i < len(a) && a[i] == x {
    return i
  }
  return -1
}
func main() {
  a := []int{-2, -1, 0, 1, 1, 1, 6, 8, 8, 9, 10}
  for x := -5; x <= 15; x++ {
    i := binarySearch(a, x)
    if i == -1 {
      fmt.Println("Value", x, "not found")
    } else {
      fmt.Println("Value", x, "found at index", i)
    }
  }
}

or

package main
import (
  "fmt"
  "sort"
)
func binarySearch(a []T, x T) int {
  f := func(i int) bool { return a[i] >= x }
  i := sort.Search(len(a), f)
  if i < len(a) && a[i] == x {
    return i
  }
  return -1
}
type T int
func main() {
  a := []T{-2, -1, 0, 1, 1, 1, 6, 8, 8, 9, 10}
  for x := T(-5); x <= 15; x++ {
    i := binarySearch(a, x)
    if i == -1 {
      fmt.Println("Value", x, "not found")
    } else {
      fmt.Println("Value", x, "found at index", i)
    }
  }
}

125. Measure function call duration

measure the duration t, in nano seconds, of a call to the function foo. Print this duration.

函数调用时间

package main
import (
  "fmt"
  "time"
)
func main() {
  t1 := time.Now()
  foo()
  t := time.Since(t1)
  ns := int64(t / time.Nanosecond)
  // Note that the clock is fixed in the Playground, so the resulting duration is always zero
  fmt.Printf("%dns\n", ns)
}
func foo() {
  fmt.Println("Hello")
}
Hello
0ns

or

package main
import (
  "fmt"
  "time"
)
func main() {
  t1 := time.Now()
  foo()
  t := time.Since(t1)
  ns := t.Nanoseconds()
  fmt.Printf("%dns\n", ns)
}
func foo() {
  fmt.Println("Hello")
}
Hello
0ns
use std::time::{Duration, Instant};
let start = Instant::now();
foo();
let duration = start.elapsed();
println!("{}", duration);

126. Multiple return values

Write a function foo that returns a string and a boolean value.

多个返回值

package main
import (
  "fmt"
)
func main() {
  s, b := foo()
  fmt.Println(s, b)
}
func foo() (string, bool) {
  return "Too good to be", true
}
fn foo() -> (String, bool) {
    (String::from("bar"), true)
}
fn main() {
    println!("{:?}", foo());
}

128. Breadth-first traversing of a tree

Call a function f on every node of a tree, in breadth-first prefix order

树的广度优先遍历

package main
import "fmt"
func (root *Tree) Bfs(f func(*Tree)) {
  if root == nil {
    return
  }
  queue := []*Tree{root}
  for len(queue) > 0 {
    t := queue[0]
    queue = queue[1:]
    f(t)
    queue = append(queue, t.Children...)
  }
}
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) {
  fmt.Printf("%v (%v)\n", node.Key, node.Deco)
}
func main() {
  tree := &Tree{Key: "World", Deco: "Our planet"}
  tree.AddChild("Europe", "A continent")
  tree.Children[0].AddChild("Germany", "A country")
  tree.Children[0].AddChild("Ireland", "A country")
  tree.Children[0].AddChild("Mediterranean Sea", "A sea")
  tree.AddChild("Asia", "A continent")
  tree.Children[0].AddChild("Japan", "A country")
  tree.Children[0].AddChild("Thailand", "A country")
  tree.Bfs(NodePrint)
}
World (Our planet)
Europe (A continent)
Asia (A continent)
Germany (A country)
Ireland (A country)
Mediterranean Sea (A sea)
Japan (A country)
Thailand (A country)
use std::collections::VecDeque;
struct Tree<V> {
    children: Vec<Tree<V>>,
    value: V
}
impl<V> Tree<V> {
    fn bfs(&self, f: impl Fn(&V)) {
        let mut q = VecDeque::new();
        q.push_back(self);
        while let Some(t) = q.pop_front() {
            (f)(&t.value);
            for child in &t.children {
                q.push_back(child);
            }
        }
    }
}
fn main() {
    let t = Tree {
        children: vec![
            Tree {
                children: vec![
                    Tree { children: vec![], value: 5 },
                    Tree { children: vec![], value: 6 }
                ],
                value: 2
            },
            Tree { children: vec![], value: 3 },
            Tree { children: vec![], value: 4 },
        ],
        value: 1
    };
    t.bfs(|v| println!("{}", v));
}
1
2
3
4
5
6

129. Breadth-first traversing in a graph

Call a function f on every vertex accessible from vertex start, in breadth-first prefix order

图的广度优先遍历

package main
import "fmt"
func (start *Vertex) Bfs(f func(*Vertex)) {
  queue := []*Vertex{start}
  seen := map[*Vertex]bool{start: true}
  for len(queue) > 0 {
    v := queue[0]
    queue = queue[1:]
    f(v)
    for next, isEdge := range v.Neighbours {
      if isEdge && !seen[next] {
        queue = append(queue, next)
        seen[next] = true
      }
    }
  }
}
type Vertex struct {
  Id         int
  Label      string
  Neighbours map[*Vertex]bool
}
type Graph []*Vertex
func NewVertex(id int, label string) *Vertex {
  return &Vertex{
    Id:         id,
    Label:      label,
    Neighbours: make(map[*Vertex]bool),
  }
}
func (v *Vertex) AddNeighbour(w *Vertex) {
  v.Neighbours[w] = true
}
func VertexPrint(v *Vertex) {
  fmt.Printf("%v (%v)\n", v.Id, v.Label)
}
func main() {
  // Some cities
  london := NewVertex(0, "London")
  ny := NewVertex(1, "New York City")
  berlin := NewVertex(2, "Berlin")
  paris := NewVertex(3, "Paris")
  tokyo := NewVertex(4, "Tokyo")
  g := Graph{
    london,
    ny,
    berlin,
    paris,
    tokyo,
  }
  _ = g
  london.AddNeighbour(paris)
  london.AddNeighbour(ny)
  ny.AddNeighbour(london)
  ny.AddNeighbour(paris)
  ny.AddNeighbour(tokyo)
  tokyo.AddNeighbour(paris)
  paris.AddNeighbour(tokyo)
  paris.AddNeighbour(berlin)
  london.Bfs(VertexPrint)
}
0 (London)
3 (Paris)
1 (New York City)
2 (Berlin)
4 (Tokyo)
use std::rc::{Rc, Weak};
use std::cell::RefCell;
struct Vertex<V> {
    value: V,
    neighbours: Vec<Weak<RefCell<Vertex<V>>>>,
}
type RcVertex<V> = Rc<RefCell<Vertex<V>>>;
struct Graph<V> {
    vertices: Vec<RcVertex<V>>,
}
impl<V> Graph<V> {
    fn new() -> Self {
        Graph { vertices: vec![] }
    }
    fn new_vertex(&mut self, value: V) -> RcVertex<V> {
        self.add_vertex(Vertex { value, neighbours: Vec::new() })
    }
    fn add_vertex(&mut self, v: Vertex<V>) -> RcVertex<V> {
        let v = Rc::new(RefCell::new(v));
        self.vertices.push(Rc::clone(&v));
        v
    }
    fn add_edge(&mut self, v1: &RcVertex<V>, v2: &RcVertex<V>) {
        v1.borrow_mut().neighbours.push(Rc::downgrade(&v2));
        v2.borrow_mut().neighbours.push(Rc::downgrade(&v1));
    }
    fn bft(start: RcVertex<V>, f: impl Fn(&V)) {
        let mut q = vec![start];
        let mut i = 0;
        while i < q.len() {
            let v = Rc::clone(&q[i]);
            i += 1;
            (f)(&v.borrow().value);
            for n in &v.borrow().neighbours {
                let n = n.upgrade().expect("Invalid neighbour");
                if q.iter().all(|v| v.as_ptr() != n.as_ptr()) {
                    q.push(n);
                }
            }
        }
    }
}
fn main() {
    let mut g = Graph::new();
    let v1 = g.new_vertex(1);
    let v2 = g.new_vertex(2);
    let v3 = g.new_vertex(3);
    let v4 = g.new_vertex(4);
    let v5 = g.new_vertex(5);
    g.add_edge(&v1, &v2);
    g.add_edge(&v1, &v3);
    g.add_edge(&v1, &v4);
    g.add_edge(&v2, &v5);
    g.add_edge(&v3, &v4);
    g.add_edge(&v4, &v5);
    Graph::bft(v1, |v| println!("{}", v));
}
1
2
3
4
5

130. Depth-first traversing in a graph

Call a function f on every vertex accessible for vertex v, in depth-first prefix order

图的深度优先遍历

package main
import "fmt"
func (v *Vertex) Dfs(f func(*Vertex), seen map[*Vertex]bool) {
  seen[v] = true
  f(v)
  for next, isEdge := range v.Neighbours {
    if isEdge && !seen[next] {
      next.Dfs(f, seen)
    }
  }
}
type Vertex struct {
  Id         int
  Label      string
  Neighbours map[*Vertex]bool
}
type Graph []*Vertex
func NewVertex(id int, label string) *Vertex {
  return &Vertex{
    Id:         id,
    Label:      label,
    Neighbours: make(map[*Vertex]bool),
  }
}
func (v *Vertex) AddNeighbour(w *Vertex) {
  v.Neighbours[w] = true
}
func VertexPrint(v *Vertex) {
  fmt.Printf("%v (%v)\n", v.Id, v.Label)
}
func main() {
  // Some cities
  london := NewVertex(0, "London")
  ny := NewVertex(1, "New York City")
  berlin := NewVertex(2, "Berlin")
  paris := NewVertex(3, "Paris")
  tokyo := NewVertex(4, "Tokyo")
  g := Graph{
    london,
    ny,
    berlin,
    paris,
    tokyo,
  }
  _ = g
  london.AddNeighbour(paris)
  london.AddNeighbour(ny)
  ny.AddNeighbour(london)
  ny.AddNeighbour(paris)
  ny.AddNeighbour(tokyo)
  tokyo.AddNeighbour(paris)
  paris.AddNeighbour(tokyo)
  paris.AddNeighbour(berlin)
  alreadySeen := map[*Vertex]bool{}
  london.Dfs(VertexPrint, alreadySeen)
}
0 (London)
3 (Paris)
4 (Tokyo)
2 (Berlin)
1 (New York City)
use std::rc::{Rc, Weak};
use std::cell::RefCell;
struct Vertex<V> {
    value: V,
    neighbours: Vec<Weak<RefCell<Vertex<V>>>>,
}
type RcVertex<V> = Rc<RefCell<Vertex<V>>>;
struct Graph<V> {
    vertices: Vec<RcVertex<V>>,
}
impl<V> Graph<V> {
    fn new() -> Self {
        Graph { vertices: vec![] }
    }
    fn new_vertex(&mut self, value: V) -> RcVertex<V> {
        self.add_vertex(Vertex { value, neighbours: Vec::new() })
    }
    fn add_vertex(&mut self, v: Vertex<V>) -> RcVertex<V> {
        let v = Rc::new(RefCell::new(v));
        self.vertices.push(Rc::clone(&v));
        v
    }
    fn add_edge(&mut self, v1: &RcVertex<V>, v2: &RcVertex<V>) {
        v1.borrow_mut().neighbours.push(Rc::downgrade(&v2));
        v2.borrow_mut().neighbours.push(Rc::downgrade(&v1));
    }
    fn dft(start: RcVertex<V>, f: impl Fn(&V)) {
        let mut s = vec![];
        Self::dft_helper(start, &f, &mut s);
    }
    fn dft_helper(start: RcVertex<V>, f: &impl Fn(&V), s: &mut Vec<*const Vertex<V>>) {
        s.push(start.as_ptr());
        (f)(&start.borrow().value);
        for n in &start.borrow().neighbours {
            let n = n.upgrade().expect("Invalid neighbor");
            if s.iter().all(|&p| p != n.as_ptr()) {
                Self::dft_helper(n, f, s);
            }
        }
    }
}
fn main() {
    let mut g = Graph::new();
    let v1 = g.new_vertex(1);
    let v2 = g.new_vertex(2);
    let v3 = g.new_vertex(3);
    let v4 = g.new_vertex(4);
    let v5 = g.new_vertex(5);
    g.add_edge(&v1, &v2);
    g.add_edge(&v1, &v4);
    g.add_edge(&v1, &v5);
    g.add_edge(&v2, &v3);
    g.add_edge(&v3, &v4);
    g.add_edge(&v4, &v5);
    Graph::dft(v1, |v| println!("{}", v));
}
1
2
3
4
5










目录
相关文章
|
6月前
|
Rust 安全 程序员
|
2月前
|
Rust Linux Go
Rust/Go语言学习
Rust/Go语言学习
|
6月前
|
Rust 安全 Java
Rust 和 Go:如何选择最适合你的编程语言
Rust 和 Go 都是优秀的选择 首先,重要的是要说 Rust 和 Go 都是非常优秀的编程语言。它们都是现代的、强大的,被广泛采用,且提供了卓越的性能。
76 1
|
6月前
|
Rust 安全 程序员
Rust vs Go:解析两者的独特特性和适用场景
在讨论 Rust 与 Go 两种编程语言哪种更优秀时,我们将探讨它们在性能、简易性、安全性、功能、规模和并发处理等方面的比较。同时,我们看看它们有什么共同点和根本的差异。现在就来看看这个友好而公平的对比。
|
Rust Go C++
Rust vs Go:常用语法对比(十三)(1)
Rust vs Go:常用语法对比(十三)(1)
83 0
|
Rust Go C++
Rust vs Go:常用语法对比(十三)(2)
Rust vs Go:常用语法对比(十三)(2)
96 1
|
Rust Go C++
Rust vs Go:常用语法对比(十二)(2)
Rust vs Go:常用语法对比(十二)(2)
84 0
|
Rust Go C++
Rust vs Go:常用语法对比(十二)(1)
Rust vs Go:常用语法对比(十二)(1)
88 0
|
Rust Go C++
Rust vs Go:常用语法对比(十一)(2)
Rust vs Go:常用语法对比(十一)(2)
72 0
|
Rust Go C++
Rust vs Go:常用语法对比(十一)(1)
Rust vs Go:常用语法对比(十一)(1)
63 0