Rust vs Go:常用语法对比(八)(2)

简介: Rust vs Go:常用语法对比(八)(2)

151. Remove string trailing path separator

Remove last character from string p, if this character is the file path separator of current platform.

Note that this also transforms unix root path "/" into the empty string!

删除字符串尾部路径分隔符

package main
import (
  "fmt"
  "io/ioutil"
  "os"
  "strings"
)
func main() {
  p := somePath()
  fmt.Println(p)
  sep := fmt.Sprintf("%c", os.PathSeparator)
  p = strings.TrimSuffix(p, sep)
  fmt.Println(p)
}
func somePath() string {
  dir, err := ioutil.TempDir("", "")
  if err != nil {
    panic(err)
  }
  p := fmt.Sprintf("%s%c%s%c", dir, os.PathSeparator, "foobar", os.PathSeparator)
  return p
}
/tmp/067319278/foobar/
/tmp/067319278/foobar

or

package main
import (
  "fmt"
  "io/ioutil"
  "os"
  "path/filepath"
  "strings"
)
func main() {
  p := somePath()
  fmt.Println(p)
  sep := fmt.Sprintf("%c", filepath.Separator)
  p = strings.TrimSuffix(p, sep)
  fmt.Println(p)
}
func somePath() string {
  dir, err := ioutil.TempDir("", "")
  if err != nil {
    panic(err)
  }
  p := fmt.Sprintf("%s%c%s%c", dir, os.PathSeparator, "foobar", os.PathSeparator)
  return p
}
/tmp/065654753/foobar/
/tmp/065654753/foobar
fn main() {
    {
        let p = "/tmp/";
        let p = if ::std::path::is_separator(p.chars().last().unwrap()) {
            &p[0..p.len() - 1]
        } else {
            p
        };
        println!("{}", p);
    }
    {
        let p = "/tmp";
        let p = if ::std::path::is_separator(p.chars().last().unwrap()) {
            &p[0..p.len() - 1]
        } else {
            p
        };
        println!("{}", p);
    }
}
/tmp
/tmp

or

fn main() {
    {
        let mut p = "/tmp/";
        p = p.strip_suffix(std::path::is_separator).unwrap_or(p);
        println!("{}", p);
    }
    {
        let mut p = "/tmp";
        p = p.strip_suffix(std::path::is_separator).unwrap_or(p);
        println!("{}", p);
    }
}
/tmp
/tmp

152. Turn a character into a string

Create string s containing only the character c.

将字符转换成字符串

package main
import (
  "fmt"
  "os"
)
func main() {
  var c rune = os.PathSeparator
  fmt.Printf("%c \n", c)
  s := fmt.Sprintf("%c", c)
  fmt.Printf("%#v \n", s)
}
/ 
"/" 
fn main() {
    let c = 'a';
    let s = c.to_string();
    println!("{}", s);
}

153. Concatenate string with integer

Create string t as the concatenation of string s and integer i.

连接字符串和整数

package main
import (
  "fmt"
)
func main() {
  s := "Hello"
  i := 123
  t := fmt.Sprintf("%s%d", s, i)
  fmt.Println(t)
}
fn main() {
    let s = "Foo";
    let i = 1;
    let t = format!("{}{}", s, i);
    println!("{}" , t);
}

154. Halfway between two hex color codes

Find color c, the average between colors c1, c2.

c, c1, c2 are strings of hex color codes: 7 chars, beginning with a number sign # . Assume linear computations, ignore gamma corrections.

求两个十六进制颜色代码的中间值

package main
import (
  "fmt"
  "strconv"
  "strings"
)
// For concision, halfway assume valid inputs.
// Caller must have explicitly checked that c1, c2 are well-formed color codes.
func halfway(c1, c2 string) string {
  r1, _ := strconv.ParseInt(c1[1:3], 16, 0)
  r2, _ := strconv.ParseInt(c2[1:3], 16, 0)
  r := (r1 + r2) / 2
  g1, _ := strconv.ParseInt(c1[3:5], 16, 0)
  g2, _ := strconv.ParseInt(c2[3:5], 16, 0)
  g := (g1 + g2) / 2
  b1, _ := strconv.ParseInt(c1[5:7], 16, 0)
  b2, _ := strconv.ParseInt(c2[5:7], 16, 0)
  b := (b1 + b2) / 2
  c := fmt.Sprintf("#%02X%02X%02X", r, g, b)
  return c
}
func main() {
  c1 := "#15293E"
  c2 := "#012549"
  if err := checkFormat(c1); err != nil {
    panic(fmt.Errorf("Wrong input %q: %v", c1, err))
  }
  if err := checkFormat(c2); err != nil {
    panic(fmt.Errorf("Wrong input %q: %v", c2, err))
  }
  c := halfway(c1, c2)
  fmt.Println("The average of", c1, "and", c2, "is", c)
}
func checkFormat(color string) error {
  if len(color) != 7 {
    return fmt.Errorf("Hex colors have exactly 7 chars")
  }
  if color[0] != '#' {
    return fmt.Errorf("Hex colors start with #")
  }
  isNotDigit := func(c rune) bool { return (c < '0' || c > '9') && (c < 'a' || c > 'f') }
  if strings.IndexFunc(strings.ToLower(color[1:]), isNotDigit) != -1 {
    return fmt.Errorf("Forbidden char")
  }
  return nil
}
package main
import (
  "fmt"
  "strconv"
  "strings"
)
// For concision, halfway assume valid inputs.
// Caller must have explicitly checked that c1, c2 are well-formed color codes.
func halfway(c1, c2 string) string {
  var buf [7]byte
  buf[0] = '#'
  for i := 0; i < 3; i++ {
    sub1 := c1[1+2*i : 3+2*i]
    sub2 := c2[1+2*i : 3+2*i]
    v1, _ := strconv.ParseInt(sub1, 16, 0)
    v2, _ := strconv.ParseInt(sub2, 16, 0)
    v := (v1 + v2) / 2
    sub := fmt.Sprintf("%02X", v)
    copy(buf[1+2*i:3+2*i], sub)
  }
  c := string(buf[:])
  return c
}
func main() {
  c1 := "#15293E"
  c2 := "#012549"
  if err := checkFormat(c1); err != nil {
    panic(fmt.Errorf("Wrong input %q: %v", c1, err))
  }
  if err := checkFormat(c2); err != nil {
    panic(fmt.Errorf("Wrong input %q: %v", c2, err))
  }
  c := halfway(c1, c2)
  fmt.Println("The average of", c1, "and", c2, "is", c)
}
func checkFormat(color string) error {
  if len(color) != 7 {
    return fmt.Errorf("Hex colors have exactly 7 chars")
  }
  if color[0] != '#' {
    return fmt.Errorf("Hex colors start with #")
  }
  isNotDigit := func(c rune) bool { return (c < '0' || c > '9') && (c < 'a' || c > 'f') }
  if strings.IndexFunc(strings.ToLower(color[1:]), isNotDigit) != -1 {
    return fmt.Errorf("Forbidden char")
  }
  return nil
}
use std::str::FromStr;
use std::fmt;
#[derive(Debug)]
struct Colour {
    r: u8,
    g: u8,
    b: u8
}
#[derive(Debug)]
enum ColourError {
    MissingHash,
    InvalidRed,
    InvalidGreen,
    InvalidBlue
}
impl fmt::Display for Colour {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
    }
}
impl FromStr for Colour {
    type Err = ColourError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if !s.starts_with('#') {
            Err(ColourError::MissingHash)
        } else {
            Ok(Colour {
                r: u8::from_str_radix(&s[1..3], 16).map_err(|_| ColourError::InvalidRed)?,
                g: u8::from_str_radix(&s[3..5], 16).map_err(|_| ColourError::InvalidGreen)?,
                b: u8::from_str_radix(&s[5..7], 16).map_err(|_| ColourError::InvalidBlue)?
            })
        }
    }
}
fn mid_colour(c1: &str, c2: &str) -> Result<String, ColourError> {
    let c1 = c1.parse::<Colour>()?;
    let c2 = c2.parse::<Colour>()?;
    let c = Colour {
        r: (((c1.r as u16) + (c2.r as u16))/2) as u8,
        g: (((c1.g as u16) + (c2.g as u16))/2) as u8,
        b: (((c1.b as u16) + (c2.b as u16))/2) as u8
    };
    Ok(format!("{}", c))
}
fn main() {
    println!("{}", mid_colour("#15293E", "#012549").unwrap())
}

155. Delete file

Delete from filesystem the file having path filepath.

删除文件

package main
import (
  "fmt"
  "io/ioutil"
  "os"
)
func main() {
  for _, filepath := range []string{
    "/tmp/foo.txt",
    "/tmp/bar.txt",
    "/tmp/foo.txt",
  } {
    err := os.Remove(filepath)
    if err == nil {
      fmt.Println("Removed", filepath)
    } else {
      fmt.Fprintln(os.Stderr, err)
    }
  }
}
func init() {
  err := ioutil.WriteFile("/tmp/foo.txt", []byte(`abc`), 0644)
  if err != nil {
    panic(err)
  }
}
Removed /tmp/foo.txt
remove /tmp/bar.txt: no such file or directory
remove /tmp/foo.txt: no such file or directory
use std::fs;
fn main() {
    let filepath = "/tmp/abc";
    println!("Creating {}", filepath);
    let _file = fs::File::create(filepath);
    let b = std::path::Path::new(filepath).exists();
    println!("{} exists: {}", filepath, b);
    println!("Deleting {}", filepath);
    let r = fs::remove_file(filepath);
    println!("{:?}", r);
    let b = std::path::Path::new(filepath).exists();
    println!("{} exists: {}", filepath, b);
}
Creating /tmp/abc
/tmp/abc exists: true
Deleting /tmp/abc
Ok(())
/tmp/abc exists: false

156. Format integer with zero-padding

Assign to string s the value of integer i in 3 decimal digits. Pad with zeros if i < 100. Keep all digits if i ≥ 1000.

用零填充格式化整数

package main
import (
  "fmt"
)
func main() {
  for _, i := range []int{
    0,
    8,
    64,
    256,
    2048,
  } {
    s := fmt.Sprintf("%03d", i)
    fmt.Println(s)
  }
}
000
008
064
256
2048
fn main() {
    let i = 1;
    let s = format!("{:03}", i);
    println!("{}", s);
    let i = 1000;
    let s = format!("{:03}", i);
    println!("{}", s);
}
001
1000

157. Declare constant string

Initialize a constant planet with string value "Earth".

声明常量字符串

package main
import (
  "fmt"
)
const planet = "Earth"
func main() {
  fmt.Println("We live on planet", planet)
}
fn main() {
    const PLANET: &str = "Earth";
    println!("{}", PLANET);
}

158. Random sublist

Create a new list y from randomly picking exactly k elements from list x.

It is assumed that x has at least k elements. Each element must have same probability to be picked. Each element from x must be picked at most once. Explain if the original ordering is preserved or not.

随机子列表

package main
import (
  "fmt"
  "math/rand"
)
func main() {
  type T string
  x := []T{"Alice", "Bob", "Carol", "Dan", "Eve", "Frank", "Grace", "Heidi"}
  k := 4
  y := make([]T, k)
  perm := rand.Perm(len(x))
  for i, v := range perm[:k] {
    y[i] = x[v]
  }
  fmt.Printf("%q", y)
}
use rand::prelude::*;
let mut rng = &mut rand::thread_rng();
let y = x.choose_multiple(&mut rng, k).cloned().collect::<Vec<_>>();

159. Trie

Define a Trie data structure, where entries have an associated value. (Not all nodes are entries)

前缀树/字典树

package main
import (
  "fmt"
  "unicode/utf8"
)
type Trie struct {
  c        rune
  children map[rune]*Trie
  isLeaf   bool
  value    V
}
type V int
func main() {
  t := NewTrie(0)
  for s, v := range map[string]V{
    "to":  7,
    "tea": 3,
    "ted": 4,
    "ten": 12,
    "A":   15,
    "i":   11,
    "in":  5,
    "inn": 9,
  } {
    t.insert(s, v)
  }
  fmt.Println(t.startsWith("te", ""))
}
func NewTrie(c rune) *Trie {
  t := new(Trie)
  t.c = c
  t.children = map[rune]*Trie{}
  return t
}
func (t *Trie) insert(s string, value V) {
  if s == "" {
    t.isLeaf = true
    t.value = value
    return
  }
  c, tail := cut(s)
  child, exists := t.children[c]
  if !exists {
    child = NewTrie(c)
    t.children[c] = child
  }
  child.insert(tail, value)
}
func (t *Trie) startsWith(p string, accu string) []string {
  if t == nil {
    return nil
  }
  if p == "" {
    var result []string
    if t.isLeaf {
      result = append(result, accu)
    }
    for c, child := range t.children {
      rec := child.startsWith("", accu+string(c))
      result = append(result, rec...)
    }
    return result
  }
  c, tail := cut(p)
  return t.children[c].startsWith(tail, accu+string(c))
}
func cut(s string) (head rune, tail string) {
  r, size := utf8.DecodeRuneInString(s)
  return r, s[size:]
}
struct Trie {
    val: String,
    nodes: Vec<Trie>
}

160. Detect if 32-bit or 64-bit architecture

Execute f32() if platform is 32-bit, or f64() if platform is 64-bit.

This can be either a compile-time condition (depending on target) or a runtime detection.

检测是32位还是64位架构

package main
import (
  "fmt"
  "strconv"
)
func main() {
  if strconv.IntSize == 32 {
    f32()
  }
  if strconv.IntSize == 64 {
    f64()
  }
}
func f32() {
  fmt.Println("I am 32-bit")
}
func f64() {
  fmt.Println("I am 64-bit")
}
fn main() {
    match std::mem::size_of::<&char>() {
        4 => f32(),
        8 => f64(),
        _ => {}
    }
}
fn f32() {
    println!("I am 32-bit");
}
fn f64() {
    println!("I am 64-bit");
}
目录
相关文章
|
21天前
|
安全 Java Go
Java vs. Go:并发之争
【4月更文挑战第20天】
31 1
|
21天前
|
算法 Java Go
Go vs Java:内存管理与垃圾回收机制对比
对比了Go和Java的内存管理与垃圾回收机制。Java依赖JVM自动管理内存,使用堆栈内存并采用多种垃圾回收算法,如标记-清除和分代收集。Go则提供更多的手动控制,内存分配与释放由分配器和垃圾回收器协同完成,使用三色标记算法并发回收。示例展示了Java中对象自动创建和销毁,而Go中开发者需注意内存泄漏。选择语言应根据项目需求和技术栈来决定。
|
8天前
|
存储 JSON Java
【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析(三)
在 Go 语言里,符合语言习惯的做法是使用一个单独的返回值来传递错误信息。
26 0
|
8天前
|
存储 Go C++
【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析(二)
Go 语言中的复合数据类型包括数组、切片(slice)、映射(map)和结构体(struct)。
34 0
|
8天前
|
Java 编译器 Go
【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析(一)
本文主要梳理自第六届字节跳动青训营(后端组)-Go语言原理与实践第一节(王克纯老师主讲)。
33 1
|
9天前
|
编译器 Go
Go 语言基础语法
Go 语言基础语法
19 1
|
15天前
|
Rust 安全 Java
Rust 和 Go:如何选择最适合你的编程语言
Rust 和 Go 都是优秀的选择 首先,重要的是要说 Rust 和 Go 都是非常优秀的编程语言。它们都是现代的、强大的,被广泛采用,且提供了卓越的性能。
25 1
|
19天前
|
存储 Go C语言
【GO基础】GO基础语法一
【GO基础】GO基础语法一
|
21天前
|
Java Linux Go
一文带你速通Go语言基础语法
本文是关于Go语言的入门介绍,作者因其简洁高效的特性对Go语言情有独钟。文章首先概述了Go语言的优势,包括快速上手、并发编程简单、设计简洁且功能强大,以及丰富的标准库。接着,文章通过示例展示了如何编写和运行Go代码,包括声明包、导入包和输出语句。此外,还介绍了Go的语法基础,如变量类型(数字、字符串、布尔和复数)、变量赋值、类型转换和默认值。文章还涉及条件分支(if和switch)和循环结构(for)。最后,简要提到了Go函数的定义和多返回值特性,以及一些常见的Go命令。作者计划在后续文章中进一步探讨Go语言的其他方面。
19 0
|
21天前
|
Java Go 云计算
【Go语言专栏】Go语言语法基础详解
【4月更文挑战第30天】Go语言,因简洁、高效和并发处理能力深受开发者喜爱,尤其在云计算和微服务领域广泛应用。本文为初学者详解Go语法基础,包括静态类型、垃圾回收、并发编程、错误处理和包管理。通过学习,读者将理解Go语言设计哲学,掌握其语法,以提升开发效率。Go的并发核心是协程和通道,而错误处理采用显式方式,增强了代码的健壮性。Go的包管理机制支持模块化开发。了解这些基础,将助你更好地探索Go语言的世界及其未来潜力。