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

Go语言零基础入门指南(下篇)(go语言入门书)

liuian 2025-05-09 20:02 43 浏览

1. 并发编程

goroutine基础

Go版本:

func say(s string) {
    for i := 0; i < 3; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world") // 启动goroutine
    say("hello")
}

对比Python线程:

import threading

def say(s):
    for i in range(3):
        time.sleep(0.1)
        print(s)

threading.Thread(target=say, args=("world",)).start()
say("hello")

对比JavaScript异步:

async function say(s) {
    for (let i = 0; i < 3; i++) {
        await new Promise(resolve => setTimeout(resolve, 100));
        console.log(s);
    }
}

say("world");
say("hello");

关键区别:

  1. goroutine比线程更轻量(初始仅2KB栈)
  2. Go运行时自动调度goroutine到OS线程
  3. 语法简单,只需go关键字

channel通信

Go版本:

func sum(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    c <- sum // 发送结果到channel
}

func main() {
    s := []int{7, 2, 8, -9, 4, 0}
    c := make(chan int)
    go sum(s[:len(s)/2], c)
    go sum(s[len(s)/2:], c)
    x, y := <-c, <-c // 从channel接收
    fmt.Println(x, y, x+y)
}

对比Python多进程:

from multiprocessing import Pipe

def sum(s, conn):
    conn.send(sum(s))
    conn.close()

parent_conn, child_conn = Pipe()
p1 = Process(target=sum, args=(s[:len(s)//2], child_conn))
p2 = Process(target=sum, args=(s[len(s)//2:], child_conn))
p1.start(); p2.start()
print(parent_conn.recv(), parent_conn.recv())

关键区别:

  1. channel是Go内置的线程安全通信机制
  2. 可以带缓冲(make(chan int, 100))
  3. 支持关闭channel和range遍历

select多路复用

Go版本:

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

对比JavaScript Promise.race:

async function fibonacci(callback, quitSignal) {
    let x = 0, y = 1;
    while (true) {
        const result = await Promise.race([
            new Promise(res => callback(res, x)),
            quitSignal
        ]);
        if (result === 'quit') return;
        [x, y] = [y, x + y];
    }
}

关键区别:

  1. select可以同时监控多个channel
  2. 常用于超时控制:
   select {
   case res := <-c:
       fmt.Println(res)
   case <-time.After(1 * time.Second):
       fmt.Println("timeout")
   }

2. 文件操作与IO

文件读写

Go版本:

// 读取文件
data, err := os.ReadFile("test.txt")
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(data))

// 写入文件
err = os.WriteFile("output.txt", []byte("Hello"), 0644)
if err != nil {
    log.Fatal(err)
}

对比Python:

with open('test.txt') as f:
    data = f.read()

with open('output.txt', 'w') as f:
    f.write("Hello")

对比JavaScript:

const fs = require('fs');
fs.readFile('test.txt', (err, data) => {
    console.log(data.toString());
});

fs.writeFile('output.txt', 'Hello', err => {});

JSON处理

Go版本:

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

// 编码
p := Person{"Alice", 25}
jsonData, _ := json.Marshal(p)

// 解码
var p2 Person
json.Unmarshal(jsonData, &p2)

对比Python:

import json

data = json.dumps({"name": "Alice", "age": 25})
p = json.loads(data)

对比JavaScript:

const data = JSON.stringify({name: "Alice", age: 25});
const p = JSON.parse(data);

关键区别:

  1. Go需要定义结构体对应JSON结构
  2. 字段标签控制JSON属性名
  3. 编解码可能返回错误需要处理

3. 测试与性能

单元测试

Go版本:

// math.go
func Add(a, b int) int {
    return a + b
}

// math_test.go
func TestAdd(t *testing.T) {
    result := Add(2, 3)
    if result != 5 {
        t.Errorf("Expected 5, got %d", result)
    }
}

运行测试:

go test

对比Python unittest:

import unittest

def add(a, b):
    return a + b

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)

基准测试

Go版本:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(1, 2)
    }
}

运行基准测试:

go test -bench=.

4. 项目实践

简单HTTP服务

Go版本:

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", helloHandler)
    http.ListenAndServe(":8080", nil)
}

对比Python Flask:

from flask import Flask
app = Flask(__name__)

@app.route('/<name>')
def hello(name):
    return f"Hello, {name}!"

app.run(port=8080)

对比JavaScript Express:

const express = require('express');
const app = express();

app.get('/:name', (req, res) => {
    res.send(`Hello, ${req.params.name}!`);
});

app.listen(8080);

项目结构建议

典型Go项目布局:

myapp/
├── cmd/
│   └── myapp/
│       └── main.go
├── internal/
│   ├── handler/
│   ├── service/
│   └── repository/
├── pkg/
│   └── utils/
├── go.mod
├── go.sum
└── README.md

进一步学习资源

  1. 官方文档:https://golang.org/doc/
  2. 标准库参考:https://pkg.go.dev/std
  3. 经典书籍:《Go程序设计语言》《Go语言实战》
  4. 开源项目:Docker, Kubernetes, Etcd等Go项目源码

下篇介绍了Go最强大的并发特性和实际项目开发中的关键技能。Go通过goroutine和channel提供了独特的并发编程模型,相比其他语言的线程/异步方案更加简单高效。建议通过实际项目练习来巩固这些概念,逐步掌握Go语言的精髓。

相关推荐

笔记本电脑键盘不能用了怎么办

如果是键盘驱动异常,更新键盘驱动即可,1、在开始里找到windows系统。2、打开控制面板,选择硬件与声音。3、点击设备和打印机选择笔记本,点击硬件找到键盘。4、点击改变设置,选择更改驱动程序。5、选...

深圳平板电脑厂家排名(深圳平板电脑厂家排名榜)

乐福尔的平板电脑还不错。原因是其功能全面,触控灵敏,屏幕显示效果好,外观设计美观,适合用来阅读、写作、观看视频等多种用途。此外,乐福尔平板电脑还具有长时间续航和较快的处理速度,能够满足用户日常使用的需...

苹果手机五笔输入法(五笔输入法手机版下载)

苹果手机有五笔的输入法,苹果手机自带输入法无五笔输入法,需要在AppStore下载一个五笔输入法,然后再添加到键盘中。工具/材料:苹果6手机1、打开手机桌面的appstore应用软件。2、然后搜索...

万能app破解器(万能app软件破解器)

1、以现有的技术手段,是没有办法破解WPA的加密方式(现在基本上全部WIFI的加密方式),WPA的加密方式安全性很高,根本就破不了。2、即使破解密码,人家也有可能设置了MAC地址过滤,还是上不去。3、...

笔记本电脑自带摄像头怎么开启

要使用笔记本电脑自带的摄像头,请按照以下步骤操作:1.打开你的电脑,进入桌面。2.定位摄像头,通常在笔记本电脑的上部或者展开的屏幕的中央位置。3.双击摄像头图标,或者在键盘上按下对应的快捷键,以...

怎么知道wifi密码(手机连接上wifi怎么知道wifi密码)

关于这个问题,如果您想查看已经连接过的无线网络密码,请按照以下步骤操作:对于Windows10:1.点击任务栏中的WiFi图标,选择“网络和Internet设置”2.在“网络和Internet设...

电脑如何调出任务管理器(电脑如何调出任务管理器快捷键)

在Windows操作系统中,可以通过以下方法调出任务管理器:使用快捷键:按下“Ctrl+Shift+Esc”快捷键组合,即可快速打开任务管理器。使用组合键:按下“Ctrl+Alt+...

win732位怎么还原系统(win732位gho)

系统安装失败,在以前的系统没有备份的情况下,是不能恢复的。只要诺顿开始运行,,不管进度条在什么位置,原系统都被格式化。如果有备份文件,那么方法是:1、打开系统备份还原软件:2、点击浏览,找到备份文件,...

电脑装什么杀毒软件(电脑装什么杀毒软件最安全)

好用的电脑杀毒软件,目前比较知名的有360杀软,腾讯电脑管家,金山毒霸,瑞星等杀毒软件,至于哪一个更好用,就看你自己的习惯了,我个人觉得360比较让人放心一些,这些年也一直用着360,比较安全有保证,...

u盘uefi是什么意思(u盘用uefi模式启动)

u盘启动盘是指在U盘里安装PE版的操作系统后,把系统设置成从U盘启动,然后电脑开机就从U盘开始重装系统。UEFI,全称“统一的可扩展固件接口”,是一种详细描述类型接口的标准。这种接口用于操作系统自动...

qq更新版本下载安装(qq号下载安装2020最新版)
  • qq更新版本下载安装(qq号下载安装2020最新版)
  • qq更新版本下载安装(qq号下载安装2020最新版)
  • qq更新版本下载安装(qq号下载安装2020最新版)
  • qq更新版本下载安装(qq号下载安装2020最新版)
win10系统故障修复工具(win10系统的故障修复界面)
  • win10系统故障修复工具(win10系统的故障修复界面)
  • win10系统故障修复工具(win10系统的故障修复界面)
  • win10系统故障修复工具(win10系统的故障修复界面)
  • win10系统故障修复工具(win10系统的故障修复界面)
天猫积分兑换根本抢不到(2021天猫积分兑换根本抢不到)

因为天猫积分的东西是有限的,但是很多人想要它们。如果你想抢到它,你最好注意启动秒杀的时间,在你启动倒计时时做好准备,并立即点击交换验证码,然后点击确认。一般最慢的时间是十秒内甚至四五秒内下单,五分钟内...

win10任务管理器未响应(win10任务管理器没反应)

未响应这种情况应该是:1、说明程序是正在运行,但由于是系统运行内存不足,或者病毒、垃圾等造成的系统卡顿了。2、可以尝试重启系统、杀毒、清理垃圾即可。解决方法一:双击“此电脑”我的电脑的时候,出现资源管...

新电脑装win7进不了系统(新电脑安装win7系统启动不了)
新电脑装win7进不了系统(新电脑安装win7系统启动不了)

解决方法:1、开机按F8,选择“最好一次正确配置”尝试修复。2、开机按F8,选择“安全模式”尝试修复。3、如果方法1,2不能修复,通过系统还原或者重新安装系统修复。二、如果软件无法修复,仍然无法启动,那么就是硬件故障原因造成的。比如硬盘、主...

2025-12-25 21:55 liuian