百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

一举两得:Go和Rust同步学习指南_rust和golang

myzbx 2025-09-06 08:23 22 浏览

变量与常量

变量声明

Go

// 显式类型声明
var x int = 10

// 类型推断
var y = 20
z := 30  // 短变量声明,只能在函数内使用

// 批量声明
var (
    a int
    b string = "hello"
    c = 3.14
)

// 默认值
var zeroInt int      // 0
var zeroStr string   // ""
var zeroBool bool    // false

Rust

// 不可变变量(默认)
let x: i32 = 10;

// 类型推断
let y = 20;

// 可变变量
let mut z = 30;
z = 40;  // 只有mut变量可以修改

// 变量遮蔽(shadowing)
let a = 5;
let a = a + 1;  // 允许同名变量,创建新绑定

// 常量(必须显式类型)
const PI: f64 = 3.14159;

// 默认不可变是Rust的重要安全特性

基本数据类型

整数类型

Go

var i8 int8 = -128
var u8 uint8 = 255
var i16 int16 = -32768
var u16 uint16 = 65535
var i32 int32 = -2147483648
var u32 uint32 = 4294967295
var i64 int64 = -9223372036854775808
var u64 uint64 = 18446744073709551615
var i int // 平台相关,32或64位
var u uint // 平台相关
var r rune = '中' // int32的别名
var b byte = 255 // uint8的别名

Rust

let i8: i8 = -128;
let u8: u8 = 255;
let i16: i16 = -32768;
let u16: u16 = 65535;
let i32: i32 = -2147483648;
let u32: u32 = 4294967295;
let i64: i64 = -9223372036854775808;
let u64: u64 = 18446744073709551615;
let isize: isize = -1; // 平台相关
let usize: usize = 1;  // 平台相关
let char = '中'; // Unicode标量值,4字节

浮点类型

Go

var f32 float32 = 3.14
var f64 float64 = 3.141592653589793

Rust

let f32: f32 = 3.14;
let f64: f64 = 3.141592653589793;

布尔类型

Go

var b1 bool = true
var b2 = false

Rust

let b1: bool = true;
let b2 = false;

字符串类型

Go

// 字符串是不可变的字节序列
var s1 string = "hello"
s2 := "world"

// 原始字符串(不转义)
s3 := `line 1
line 2\n`  // \n不会被转义

// 字符串拼接
s4 := s1 + " " + s2

Rust

// 字符串切片(不可变引用)
let s1: &str = "hello";

// String类型(可增长、可修改)
let mut s2 = String::from("world");

// 原始字符串
let s3 = r"line 1\nline 2";  // \n不会被转义
let s4 = r#"字符串可以包含"引号""#;

// 字符串拼接
let s5 = format!("{} {}", s1, s2);  // 创建新String
s2.push_str("!");  // 修改现有String

控制结构

条件语句

Go

// 基本if
if x > 0 {
    fmt.Println("positive")
}

// if with short statement
if y := compute(); y < 0 {
    fmt.Println("negative")
} else if y == 0 {
    fmt.Println("zero")
} else {
    fmt.Println("positive")
}

// switch
switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("macOS")
case "linux":
    fmt.Println("Linux")
default:
    fmt.Printf("%s\n", os)
}

// 无条件的switch(相当于if-else链)
switch {
case x < 0:
    fmt.Println("negative")
case x == 0:
    fmt.Println("zero")
default:
    fmt.Println("positive")
}

Rust

// 基本if
if x > 0 {
    println!("positive");
}

// if-else if-else
let y = compute();
if y < 0 {
    println!("negative");
} else if y == 0 {
    println!("zero");
} else {
    println!("positive");
}

// if是表达式
let result = if y > 0 { "positive" } else { "non-positive" };

// match(比switch更强大)
match x.cmp(&0) {
    std::cmp::Ordering::Less => println!("negative"),
    std::cmp::Ordering::Equal => println!("zero"),
    std::cmp::Ordering::Greater => println!("positive"),
}

// match是表达式
let number = match x {
    1 => "one",
    2 => "two",
    3..=9 => "three to nine",  // 范围匹配
    _ => "other",  // 默认情况
};

循环

Go

// 传统for循环
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// while循环(用for实现)
j := 0
for j < 10 {
    fmt.Println(j)
    j++
}

// 无限循环
for {
    if condition {
        break
    }
}

// range循环
nums := []int{1, 2, 3}
for i, num := range nums {
    fmt.Printf("index: %d, value: %d\n", i, num)
}

// 带标签的break
OuterLoop:
for i := 0; i < 10; i++ {
    for j := 0; j < 10; j++ {
        if i*j > 50 {
            break OuterLoop
        }
    }
}

Rust

// for循环(迭代器)
for i in 0..10 {  // 0..10是范围,不包括10
    println!("{}", i);
}

// while循环
let mut j = 0;
while j < 10 {
    println!("{}", j);
    j += 1;
}

// 无限循环(可返回值)
let result = loop {
    if condition {
        break 42;  // 返回42
    }
};

// 迭代集合
let nums = vec![1, 2, 3];
for (i, &num) in nums.iter().enumerate() {
    println!("index: {}, value: {}", i, num);
}

// 带标签的break
'outer: for i in 0..10 {
    for j in 0..10 {
        if i * j > 50 {
            break 'outer;
        }
    }
}

函数

基本函数

Go

// 基本函数
func add(a int, b int) int {
    return a + b
}

// 参数类型简写
func sub(a, b int) int {
    return a - b
}

// 多返回值
func swap(a, b string) (string, string) {
    return b, a
}

// 命名返回值
func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return  // 裸返回
}

// 可变参数
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

Rust

// 基本函数
fn add(a: i32, b: i32) -> i32 {
    a + b  // 没有分号,这是表达式
}

// 多返回值(使用元组)
fn swap(a: String, b: String) -> (String, String) {
    (b, a)
}

// 表达式与语句
fn five() -> i32 {
    5  // 表达式返回
}

fn plus_one(x: i32) -> i32 {
    x + 1  // 表达式返回
    // x + 1;  // 加上分号变成语句,会报错
}

// 可变参数(使用切片)
fn sum(nums: &[i32]) -> i32 {
    nums.iter().sum()
}

// 方法(关联函数)
impl Point {
    fn distance(&self, other: &Point) -> f64 {
        // 方法实现
    }
}

闭包(匿名函数)

Go

// 基本闭包
add := func(a, b int) int {
    return a + b
}
result := add(1, 2)

// 闭包捕获环境变量
x := 10
closure := func() int {
    return x * 2  // 捕获x
}
fmt.Println(closure())  // 20

Rust

// 基本闭包
let add = |a: i32, b: i32| -> i32 { a + b };
let result = add(1, 2);

// 类型推断
let add = |a, b| a + b;  // 编译器能推断类型

// 捕获环境变量
let x = 10;
let closure = || x * 2;  // 不可变借用x
println!("{}", closure());  // 20

// 移动语义(强制获取所有权)
let s = String::from("hello");
let closure = move || println!("{}", s);  // s的所有权被移动
closure();
// println!("{}", s);  // 错误!s已被移动

复合数据类型

数组

Go

// 数组(固定长度)
var a [3]int = [3]int{1, 2, 3}
b := [...]int{1, 2, 3}  // 编译器推断长度

// 访问元素
first := a[0]

// 修改元素
a[1] = 20

// 遍历
for i, v := range a {
    fmt.Printf("index: %d, value: %d\n", i, v)
}

// 多维数组
var matrix [2][3]int = [2][3]int{
    {1, 2, 3},
    {4, 5, 6},
}

Rust

// 数组(固定长度)
let a: [i32; 3] = [1, 2, 3];
let b = [1, 2, 3];  // 类型推断

// 访问元素
let first = a[0];

// 修改元素(需要mut)
let mut c = [1, 2, 3];
c[1] = 20;

// 遍历
for (i, &v) in a.iter().enumerate() {
    println!("index: {}, value: {}", i, v);
}

// 多维数组
let matrix: [[i32; 3]; 2] = [
    [1, 2, 3],
    [4, 5, 6],
];

切片/向量

Go

// 切片(动态大小视图)
s := []int{1, 2, 3}  // 切片字面量
var s2 []int         // 零值是nil

// 从数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4]  // [2, 3, 4]

// 修改切片会影响底层数组
slice[0] = 20
fmt.Println(arr)  // [1, 20, 3, 4, 5]

// 常用操作
s = append(s, 4)       // 追加
length := len(s)       // 长度
capacity := cap(s)     // 容量
sub := s[1:3]         // 子切片
copy(sub, []int{9,8}) // 复制

// make创建切片
s3 := make([]int, 5)     // 长度5,容量5
s4 := make([]int, 0, 10) // 长度0,容量10

Rust

// 切片(不可变视图)
let arr = [1, 2, 3, 4, 5];
let slice: &[i32] = &arr[1..4];  // [2, 3, 4]

// 向量(Vec,可增长数组)
let mut vec = vec![1, 2, 3];
vec.push(4);            // 追加
let first = vec[0];     // 访问
vec[1] = 20;           // 修改

// 常用操作
let len = vec.len();    // 长度
let cap = vec.capacity(); // 容量
let sub = &vec[1..3];   // 子切片
vec.extend([5,6]);      // 扩展
vec.insert(1, 10);      // 插入
vec.remove(2);          // 移除

// 迭代
for v in &vec {
    println!("{}", v);
}

结构体

Go

// 定义结构体
type Person struct {
    Name string
    Age  int
}

// 创建实例
p1 := Person{"Alice", 30}
p2 := Person{Name: "Bob", Age: 25}

// 匿名结构体
p3 := struct {
    Name string
    Age  int
}{
    Name: "Charlie",
    Age: 35,
}

// 方法
func (p Person) Greet() string {
    return fmt.Sprintf("Hello, my name is %s", p.Name)
}

// 指针接收者方法(可修改结构体)
func (p *Person) Birthday() {
    p.Age++
}

// 嵌套结构体
type Employee struct {
    Person
    JobTitle string
}

Rust

// 定义结构体
struct Person {
    name: String,
    age: i32,
}

// 创建实例
let p1 = Person {
    name: String::from("Alice"),
    age: 30,
};

// 更新语法
let p2 = Person {
    name: String::from("Bob"),
    ..p1  // 使用p1的其他字段
};

// 元组结构体
struct Color(i32, i32, i32);
let black = Color(0, 0, 0);

// 方法
impl Person {
    fn greet(&self) -> String {
        format!("Hello, my name is {}", self.name)
    }
    
    fn birthday(&mut self) {
        self.age += 1;
    }
    
    // 关联函数(类似静态方法)
    fn new(name: String, age: i32) -> Self {
        Person { name, age }
    }
}

// 嵌套结构体
struct Employee {
    person: Person,
    job_title: String,
}

枚举

Go

// Go没有原生枚举,通常用常量模拟
type Direction int

const (
    North Direction = iota
    East
    South
    West
)

func (d Direction) String() string {
    return [...]string{"North", "East", "South", "West"}[d]
}

// 带值的枚举(使用结构体和接口)
type Shape interface {
    area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) area() float64 {
    return math.Pi * c.Radius * c.Radius
}

type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) area() float64 {
    return r.Width * r.Height
}

Rust

// 基本枚举
enum Direction {
    North,
    East,
    South,
    West,
}

// 带数据的枚举
enum Shape {
    Circle(f64),          // 半径
    Rectangle(f64, f64),  // 宽和高
    Square(f64),          // 边长
}

// 方法
impl Shape {
    fn area(&self) -> f64 {
        match self {
            Shape::Circle(r) => std::f64::consts::PI * r * r,
            Shape::Rectangle(w, h) => w * h,
            Shape::Square(s) => s * s,
        }
    }
}

// Option枚举(标准库)
enum Option<T> {
    Some(T),
    None,
}

// Result枚举(标准库)
enum Result<T, E> {
    Ok(T),
    Err(E),
}

错误处理

Go

// 多返回值错误处理
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("division by zero")
    }
    return a / b, nil
}

result, err := divide(10, 0)
if err != nil {
    log.Fatal(err)
}

// 自定义错误类型
type MyError struct {
    Msg string
    Code int
}

func (e *MyError) Error() string {
    return fmt.Sprintf("code %d: %s", e.Code, e.Msg)
}

func process() error {
    return &MyError{"something went wrong", 500}
}

// panic和recover
func risky() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered:", r)
        }
    }()
    panic("something bad happened")
}

Rust

// Result类型处理
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("division by zero"))
    } else {
        Ok(a / b)
    }
}

match divide(10.0, 0.0) {
    Ok(result) => println!("Result: {}", result),
    Err(e) => println!("Error: {}", e),
}

// 更简洁的写法(使用?运算符)
fn calculate() -> Result<f64, String> {
    let x = divide(10.0, 2.0)?;  // 如果Err会提前返回
    let y = divide(x, 3.0)?;
    Ok(y)
}

// 自定义错误类型(更推荐的方式)
#[derive(Debug)]
enum MathError {
    DivisionByZero,
    NegativeLogarithm,
}

impl std::fmt::Display for MathError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            MathError::DivisionByZero => write!(f, "division by zero"),
            MathError::NegativeLogarithm => write!(f, "logarithm of negative number"),
        }
    }
}

fn better_divide(a: f64, b: f64) -> Result<f64, MathError> {
    if b == 0.0 {
        Err(MathError::DivisionByZero)
    } else {
        Ok(a / b)
    }
}

// panic和unwrap
let x: i32 = "123".parse().unwrap();  // 成功时返回值,失败时panic
let y: i32 = "abc".parse().expect("Failed to parse number");  // 自定义panic消息

并发编程

Go

// goroutine
go func() {
    fmt.Println("Running in goroutine")
}()

// WaitGroup等待多个goroutine完成
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(n int) {
        defer wg.Done()
        fmt.Println(n)
    }(i)
}
wg.Wait()

// channel通信
ch := make(chan int)
go func() {
    ch <- 42  // 发送
}()
value := <-ch  // 接收

// 缓冲channel
bufCh := make(chan int, 2)
bufCh <- 1
bufCh <- 2

// select多路复用
select {
case v := <-ch1:
    fmt.Println(v)
case v := <-ch2:
    fmt.Println(v)
case <-time.After(time.Second):
    fmt.Println("timeout")
default:
    fmt.Println("no activity")
}

// sync.Mutex互斥锁
var mu sync.Mutex
var counter int
for i := 0; i < 10; i++ {
    go func() {
        mu.Lock()
        defer mu.Unlock()
        counter++
    }()
}

Rust

// 线程
let handle = std::thread::spawn(|| {
    println!("Running in thread");
});
handle.join().unwrap();  // 等待线程结束

// 通道通信
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
    tx.send(42).unwrap();  // 发送
});
let value = rx.recv().unwrap();  // 接收

// 共享状态并发(Arc + Mutex)
use std::sync::{Arc, Mutex};
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];

for _ in 0..10 {
    let counter = Arc::clone(&counter);
    let handle = std::thread::spawn(move || {
        let mut num = counter.lock().unwrap();
        *num += 1;
    });
    handles.push(handle);
}

for handle in handles {
    handle.join().unwrap();
}

// async/await(异步编程)
async fn fetch_data() -> Result<String, reqwest::Error> {
    reqwest::get("https://example.com")
        .await?
        .text()
        .await
}

#[tokio::main]
async fn main() {
    match fetch_data().await {
        Ok(data) => println!("Got data: {}", data),
        Err(e) => println!("Error: {}", e),
    }
}

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 &quot;小贱贱&quot;韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...