字节青训翻译项目 + Golang使用笔记
基础语法
go 语言的开始 肯定少不了 Hello World
package main
import (
"fmt"
)
func main() {
fmt.Println("hello worl")
}
下划线
“_”是特殊标识符,用来忽略结果。
golang 语言一般拥有多返回值 使用一个变量接收结果,一个接收错误 或者 使用 _ 用来忽略错误
go中 的:=
和 =
输入输出
fmt 标准库的输入输出
输入
fmt.Scan()
变量类型输入fmt.Scanf()
按照指定格式获取输入fmt.Scanln()
获取一行的输入 只有一行
输出
fmt.Print()
按照变量进行输出fmt.Println()
输出并且换行fmt.Printf()
安装格式指定输出
其中输出的时候 %b| %v| %+v | %#v+|
%b
:这个占位符用于输出一个整数的二进制表示。
%v
:这是一个通用的占位符,用于输出值的默认格式。
%+v
:这个占位符与 %v
类似,但它在输出结构体时会添加字段名。
%#v
:这个占位符用于输出值的Go语法表示,包括结构体的名称和字段。
%T
: 输出 变量类型
TestCode
package main
import (
"fmt"
)
type Mystruct struct {
age int
name string
}
func main() {
var cc = [6]Mystruct{}
fmt.Scanf("%d %s", &cc[0].age, &cc[0].name)
fmt.Printf("binary : %b : %d %s \n", cc[0].age, cc[0].age, cc[0].name)
fmt.Printf("-------------------------------------\n")
fmt.Scan(&cc[1].age, &cc[1].name)
fmt.Print(cc[1])
fmt.Printf("-------------------------------------\n")
fmt.Scan(&cc[2].age)
fmt.Scanln(&cc[2].name)
println("--------------------------")
fmt.Println(cc[2].age, cc[2].name)
fmt.Printf("-------------------------------------\n")
fmt.Printf("%v\n%+v\n%#v\n%+#v\n%T\n", cc, cc, cc, cc, cc)
}
PS D:\C zhuomian\goProg\mygodemo> go run main.go 11 ondeone
binary : 1011 : 11 ondeone
22 twotwo {22 twotwo}-------------------------------------
33
33
[{11 ondeone} {22 twotwo} {33 } {0 } {0 } {0 }] [{age:11 name:ondeone} {age:22 name:twotwo} {age:33 name:} {age:0 name:} {age:0 name:} {age:0 name:}] [6]main.Mystruct{main.Mystruct{age:11, name:"ondeone"}, main.Mystruct{age:22, name:"twotwo"}, main.Mystruct{age:33, name:""}, main.Mystruct{age:0, name:""}, main.Mystruct{age:0, name:""}, main.Mystruct{age:0, name:""}} [6]main.Mystruct{main.Mystruct{age:11, name:"ondeone"}, main.Mystruct{age:22, name:"twotwo"}, main.Mystruct{age:33, name:""}, main.Mystruct{age:0, name:""}, main.Mystruct{age:0, name:""}, main.Mystruct{age:0, name:""}} [6]main.Mystruct
手动实现mygoguess-game.go
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
MAXnum := 19999
rand.Seed(time.Now().UnixNano()) //seed 随机种子
randd := rand.Intn(MAXnum) // 随机数
var innum int
fmt.Println("请输入一个数字")
for {
fmt.Scanln(&innum)
if innum == randd {
fmt.Println("恭喜你猜对了")
break
}
if innum > randd {
fmt.Println("你猜的数字大了")
}
if innum < randd {
fmt.Println("你猜的数字小了")
}
}
}
Sprint
系列函数
fmt.Sprint
,fmt.Sprintf
,fmt.Sprintln
等函数都属于Sprint
系列。功能:这些函数会根据传入的参数生成一个字符串并返回。
fmt.Sprint(args...)
:直接将参数拼接成字符串。fmt.Sprintf(format, args...)
:根据format
的格式生成字符串(类似于 C 中的printf
)。fmt.Sprintln(args...)
:会在参数之间加入空格,并在结尾加上换行符。
Errorf
函数
功能:
fmt.Errorf
根据格式化参数生成一个错误类型error
。err := fmt.Errorf("an error occurred: %d", errorCode)
用法:适用于生成带有格式化信息的错误,便于调试。
Sscan
系列函数
这些函数从字符串中扫描数据并解析到变量中:
Sscan
功能:从字符串中依次读取数据,将其解析为传入的变量。
用法:
var name string var age int fmt.Sscan("Alice 30", &name, &age) // name = "Alice", age = 30
Sscanln
功能:与
Sscan
类似,但在遇到换行符时会停止扫描。用法:
var name string var age int fmt.Sscanln("Alice 30\n", &name, &age) // name = "Alice", age = 30
Sscanf`
功能:从字符串中按指定格式读取数据。
用法:
var name string var age int fmt.Sscanf("Name: Alice Age: 30", "Name: %s Age: %d", &name, &age) // name = "Alice", age = 30
Fscan
系列函数
这些函数用于从 io.Reader
类型中读取数据。常见的 io.Reader
类型包括文件、标准输入等。
Fscan
功能:从
Reader
中逐行读取数据并解析到变量。用法:
var name string var age int fmt.Fscan(reader, &name, &age)
Fscanln
功能:与
Fscan
类似,但遇到换行符时停止扫描。用法:
var name string var age int fmt.Fscanln(reader, &name, &age)
Fscanf
功能:按指定格式从
Reader
中读取数据。用法:
var name string var age int fmt.Fscanf(reader, "Name: %s Age: %d", &name, &age)
bufio.NewReader
和 bufio
库
bufio
是 Go 标准库中的缓冲读取库。bufio.NewReader
可以创建一个带缓冲的读取器,用于更高效地从输入源读取数据。
bufio.NewReader
用法:reader := bufio.NewReader(os.Stdin)
创建一个基于标准输入(
os.Stdin
)的带缓冲读取器reader
。使用
reader.ReadString('\n')
可以读取一行输入,直到遇到换行符。
bufio
库的优势:使用缓冲提高读取效率:
bufio.Reader
会在内存中维护一个缓冲区,减少底层 I/O 操作次数,提高读取性能。提供了如
ReadLine
、ReadString
等方便的方法,可以轻松读取多种数据格式。
bufio包
一、读取函数
bufio.Reader
提供的缓冲读取功能使得读取数据更高效且便捷。创建 Reader
可以通过 bufio.NewReader
来实现:
reader := bufio.NewReader(os.Stdin)
常用读取方法
ReadByte
功能:读取并返回一个字节。
用法:
b, err := reader.ReadByte()
ReadRune
功能:读取一个 Unicode 字符(rune),返回该字符及其字节大小。
用法:常用于读取 UTF-8 编码的字符。
r, size, err := reader.ReadRune()
ReadString
功能:读取直到指定的分隔符(如
'\n'
)并返回字符串。用法:适合按行读取用户输入。
input, err := reader.ReadString('\n')
ReadLine`
功能:按行读取数据,返回一行内容,不包含行尾的换行符。适合处理长行数据,因为可以分段读取。
用法:
line, isPrefix, err := reader.ReadLine()
isPrefix
:为true
表示当前行未读完,需继续读取。
ReadBytes
功能:读取到指定的字节(分隔符)并返回
[]byte
数组。用法:适合需要读取特定分隔符时使用。
data, err := reader.ReadBytes('\n')
Peek
功能:从缓冲区中查看前
n
个字节,而不移动读取位置。适合检查接下来要处理的数据。用法:
peekBytes, err := reader.Peek(5)
Buffered
功能:返回缓冲区中现有的未读取字节数。
用法:可用于检查缓冲区中是否有足够数据。
bufferedBytes := reader.Buffered()
二、写入函数
bufio.Writer
提供了缓冲写入功能,可以减少 I/O 操作次数,从而提高效率。创建 Writer
可以通过 bufio.NewWriter
来实现:
writer := bufio.NewWriter(os.Stdout)
常用写入方法
Write
功能:直接将
[]byte
写入缓冲区。用法:
writer.Write([]byte("Hello"))
WriteByte
功能:将单个字节写入缓冲区。
用法:
writer.WriteByte('H')
WriteRune
功能:将 Unicode 字符写入缓冲区,适合写入 UTF-8 编码字符。
用法:
writer.WriteRune('你')
WriteString
功能:直接将字符串写入缓冲区。
用法:
writer.WriteString("Hello, World!")
Flush
功能:将缓冲区内容立即写入底层
io.Writer
(如os.Stdout
)。用法:在完成一系列写入后需要
Flush
,确保数据被实际写出。writer.Flush()
Buffered
功能:返回缓冲区中尚未写入的字节数。
用法:可用于检查缓冲区是否快满或为空。
bufferedBytes := writer.Buffered()
Test
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
fmt.Print("请输入一行文本:")
// 读取一行输入
input, _ := reader.ReadString('\n')
// 转换为大写
input = strings.ToUpper(input)
// 写入到输出缓冲区
writer.WriteString("转换为大写后:" + input)
// Flush 输出缓冲区内容
writer.Flush()
}
bufio.Reader
:提供多种读取方法,方便逐字节、逐行、指定长度等方式读取数据。bufio.Writer
:在缓冲区中收集数据,统一Flush
输出,减少 I/O 操作频率。
go 翻译 小 demo
使用工具
在线JSON转Golang Struct - JSON中文网
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
)
type JSONData []struct {
Translations []struct {
Text string `json:"text"`
Transliteration struct {
Text string `json:"text"`
Script string `json:"script"`
} `json:"transliteration"`
To string `json:"to"`
SentLen struct {
SrcSentLen []int `json:"srcSentLen"`
TransSentLen []int `json:"transSentLen"`
} `json:"sentLen"`
} `json:"translations"`
DetectedLanguage struct {
Language string `json:"language"`
} `json:"detectedLanguage"`
}
func main() {
if len(os.Args) != 2 {
fmt.Print("Err < 2")
os.Exit(1)
}
word := os.Args[1]
client := &http.Client{}
headl := "&fromLang=en&to=zh-Hans&token=cfdSz0lBcTJ0mYIx-idHdwW2WsB7BWeb&key=1730728315435&text="
headr := "%0A&tryFetchingGenderDebiasedTranslations=true"
var data = strings.NewReader(headl + word + headr)
req, err := http.NewRequest("POST", "https://cn.bing.com/ttranslatev3?&IG=0D2DD352B09B429AA737FF0B91CF7E3A&IID=SERP.5611", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("accept", "*/*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9,en-US;q=0.8,en-GB;q=0.7,en;q=0.6")
req.Header.Set("content-type", "application/x-www-form-urlencoded")
req.Header.Set("cookie", "_EDGE_V=1; MUID=3DD806F5E6F96D3724B6122BE7BA6C66; MUIDB=3DD806F5E6F96D3724B6122BE7BA6C66; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=E28660BFF60D4F238469111E446AE1FC&dmnchg=1; ANON=A=E937F8F3346CF4C763B336C0FFFFFFFF; MMCASM=ID=DA0EBA777BC94EADAC77E8AADA144F7C; _UR=QS=0&TQS=0&Pn=0; MUIDB=3DD806F5E6F96D3724B6122BE7BA6C66; MSPTC=-b_60jJeBZwD8J8VGqLMX_hpgKYf7fDd5ex_VUTObB0; SnrOvr=X=rebateson; _HPVN=CS=eyJQbiI6eyJDbiI6NSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiUCJ9LCJTYyI6eyJDbiI6NSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiSCJ9LCJReiI6eyJDbiI6NSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiVCJ9LCJBcCI6dHJ1ZSwiTXV0ZSI6dHJ1ZSwiTGFkIjoiMjAyNC0xMS0wMlQwMDowMDowMFoiLCJJb3RkIjowLCJHd2IiOjAsIlRucyI6MCwiRGZ0IjpudWxsLCJNdnMiOjAsIkZsdCI6MCwiSW1wIjoxMSwiVG9ibiI6MH0=; _clck=1t8fudo%7C2%7Cfqj%7C1%7C1724; _uetvid=65612ea0822411efbded8727e2044d11; btstkn=Tl7pY6tCC3fvzW8SLomdC00avFy%252F9M7sEUzBBeUlccpjqL2Pmat1vCmKcD95kpaM3LkSENBW62CdRAOAKad81dzIw5Md9nhjqkbZ4R0Exkw%253D; WLS=C=c21e495c9a293e97&N=%e9%91%ab%e8%87%a3; _Rwho=u=d&ts=2024-11-04; CortanaAppUID=2664D2F3F925D133F3152F684CF76B6E; _EDGE_S=SID=38C6BACFBE90697D0A75AFE2BF986891&mkt=zh-CN&ui=zh-cn; ipv6=hit=1730717206641&t=4; _tarLang=default=zh-Hans; _TTSS_IN=hist=WyJ6aC1IYW5zIiwiZW4iLCJhdXRvLWRldGVjdCJd&isADRU=0; _TTSS_OUT=hist=WyJlbiIsInpoLUhhbnMiXQ==; SRCHUSR=DOB=20240817&T=1730721490000; ABDEF=V=13&ABDV=13&MRNB=1730721613137&MRB=0; _SS=SID=38C6BACFBE90697D0A75AFE2BF986891&R=2746&RB=2746&GB=0&RG=17915&RP=2746&PC=U531; GC=YnxFrylq8fwg8A7dhcQYV3GTNjCGYaOAsyyTi2egLrQWNaNwWTDvA38X8hkfihz8YH0TSCq3AHgfoE60Nd8m3w; SRCHHPGUSR=SRCHLANG=zh-Hans&PV=15.0.0&DM=0&BRW=NOTP&BRH=T&CW=804&CH=1202&SCW=1164&SCH=3115&DPR=1.3&UTC=480&EXLTT=32&HV=1730721638&PRVCW=804&PRVCH=1202&BZA=0&THEME=0&WEBTHEME=0&PR=1.25&IG=A29C8756EB9A4FB498E60F5F0D275D1D; _RwBf=r=1&mta=0&rc=2746&rb=2746&gb=0&rg=17915&pc=2746&mtu=0&rbb=0.0&g=0&cid=&clo=0&v=16&l=2024-11-04T08:00:00.0000000Z&lft=0001-01-01T00:00:00.0000000&aof=0&ard=0001-01-01T00:00:00.0000000&rwdbt=1730524633&rwflt=1730508731&o=16&p=MULTIGENREWARDSCMACQ202205&c=ML2357&t=3238&s=2022-12-05T12:33:52.9946010+00:00&ts=2024-11-04T12:00:36.7461101+00:00&rwred=0&wls=0&wlb=0&wle=0&ccp=2&cpt=0&lka=0&lkt=0&aad=0&TH=&e=_NWZuWI9JkZbPZYLV3BRPfM8SAZ-FNeWAsJADUHG_-kwyhHr4Ie8SfV3DWoDU3-7IYvYoVCIHD2HwMurudshQg&A=E937F8F3346CF4C763B336C0FFFFFFFF&rwaul2=0&rwmrst=2024-09-25T09:00:23+08:00; SNRHOP=I=&TS=; _U=1TBYMmfO53oLk8kA_5z2YZ8qulngPq15SyUZ8kHniyTE6nQnuJklbyUjUlJVw1NpXZTq55JZ-NF0PDIFqtO21-2M4xQADotvnQpqejAm-9p_W2gpL7fbr1C8zXuSHp96eDt44Tnsrv9IG36_phkVHdtjy99ckx0qdFyvAUGBwlHpJrsd1-WY7YExjYQwll3Sm1brlLVTG7mhMcrsxXoYbx_ngU-5zW5cL5J7HZkzEogA; TTRSL=en; USRLOC=HS=1&ELOC=LAT=36.65978240966797|LON=117.00499725341797|N=%E5%B8%82%E4%B8%AD%E5%8C%BA%EF%BC%8C%E5%B1%B1%E4%B8%9C%E7%9C%81|ELT=2|&CLOC=LAT=36.6597836352021|LON=117.0049957676959|A=733.4464586120832|TS=241104125942|SRC=W&BID=MjQxMTA0MjA1OTM4X2EzY2Y5OTFjMjU4NzJiNTg4YTNiNzg1MTc4MDdlNmM4NTUyNTg2YTg1ODIzZTMxNDUzMjUxNzg2ZmJhZWFlNGE=")
req.Header.Set("dnt", "1")
req.Header.Set("ect", "4g")
req.Header.Set("origin", "https://cn.bing.com")
req.Header.Set("priority", "u=1, i")
req.Header.Set("referer", "https://cn.bing.com/search?q=%E7%BF%BB%E8%AF%91&cvid=07c4651890094e5fba232ebb078db1ec&gs_lcrp=EgRlZGdlKgYIABBFGDsyBggAEEUYOzIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRBFGD0yBggGEEUYPTIGCAcQRRg9MgYICBBFGEHSAQgyNzI2ajBqNKgCALACAA&FORM=ANAB01&PC=U531&form=TTSREF&isTTRefreshQuery=1")
req.Header.Set("sec-ch-ua", `"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"`)
req.Header.Set("sec-ch-ua-arch", `"x86"`)
req.Header.Set("sec-ch-ua-bitness", `"64"`)
req.Header.Set("sec-ch-ua-full-version", `"130.0.2849.68"`)
req.Header.Set("sec-ch-ua-full-version-list", `"Chromium";v="130.0.6723.92", "Microsoft Edge";v="130.0.2849.68", "Not?A_Brand";v="99.0.0.0"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-model", `""`)
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
req.Header.Set("sec-ch-ua-platform-version", `"15.0.0"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "same-origin")
req.Header.Set("sec-ms-gec", "2422B64C0FB5B1F6FCE9D34B529E6DCAF0D006DEE052869EB585F2EF78E89026")
req.Header.Set("sec-ms-gec-version", "1-130.0.2849.68")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0")
req.Header.Set("x-client-data", "eyIxIjoiNiIsIjEwIjoiXCJKUHdxcFNUbGc2T0dzYjFCT1FOL2dkaUdvKzdoZ1dDcEFGejFNRkFOQXpJPVwiIiwiMiI6IjEiLCIzIjoiMCIsIjQiOiI1NjY4MTAzMTkwODE1NjgzNTM3IiwiNSI6IlwiZlRuTzNIY0VjV3l2bmNNWWhNanFFMEZBUzdDL2dNbm44d0VZQm9rcFFTZz1cIiIsIjYiOiJzdGFibGUiLCI3IjoiMTE1OTY0MTE2OTk0NSIsIjkiOiJkZXNrdG9wIn0=")
req.Header.Set("x-edge-shopping-flag", "1")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
var ret JSONData
aerr := json.Unmarshal(bodyText, &ret)
if aerr != nil {
log.Fatal(err)
}
fmt.Printf("%s : %s\n", word, string(ret[0].Translations[0].Text))
}
数组
数组在 Go 中是固定长度的序列,声明方式类似其他语言。
切片(Slice)
切片是对数组的抽象,不是数组或数组指针,而是通过内部指针和相关属性引用数组的一部分。
package main
import "fmt"
func main() {
// 通过数组创建切片
var arr = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
var slice1 []int = arr[2:8] // 部分数组切片
slice2 := arr[:] // 全数组切片
slice3 := arr[5:] // 从第6个元素起切片
fmt.Println(slice1)
fmt.Println(slice2)
fmt.Println(slice3)
// 使用 make 创建切片
var slice0 = make([]int, 100) // 创建长度为100的切片
fmt.Println(slice0, len(slice0), cap(slice0))
slice0 = slice3[2:3]
fmt.Println(slice0, len(slice0), cap(slice0))
}
指针
Go 的指针不能偏移和运算,因此是“安全指针”。Go 中 new
和 make
都是内存分配的函数:
new
只能接收一个参数,返回指向指定类型的指针(类似 C++ 的new
)。make
只能用于创建slice
、map
和channel
,并返回该类型的本身(非指针)。
map
map
是 Go 中无序的键值对数据结构。map
是引用类型,必须通过 make
初始化后才能使用。
创建 map 示例:
scmap := make(map[int]string)
类似 C++ STL 中的 unordered_map<int, string>
。
检查键是否存在:
value, ok := map[key]
删除键值对:
delete(map, key)
map 与切片组合使用:
map
作为切片元素:var mapSlice = make([]map[string]string, 3)
切片作为
map
值:var sliceMap = make(map[string][]string, 3)
结构体
定义结构体:
type 类型名 struct {
字段名 字段类型
字段名 字段类型
…
}
实例化结构体:
var 结构体实例 结构体类型
匿名结构体:
用于定义临时数据结构。
var user struct{Name string; Age int}
指针类型结构体:
在 Go 中,结构体指针可以直接使用 .
访问成员。
var p2 = new(person) // 创建指针类型的结构体实例
p3 := &person{} // 等价于 new(person)
构造函数:
Go 中没有内置构造函数,可以手动实现:
func newPerson(name, city string, age int8) *person {
return &person{
name: name,
city: city,
age: age,
}
}
结构体继承
通过匿名结构体实现类似继承的效果。
方法和接收者
Go 方法是特定类型的函数,其接收者(Receiver)类似于其他语言的 this
或 self
。
定义方法:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
// 方法体
}
值类型接收者:
当方法作用于值类型接收者时,Go 会复制一份接收者变量,修改仅作用于副本,无法更改原始变量。
结构体和 JSON 序列化
可以通过 json
包将结构体序列化为 JSON。
// Student 结构体
type Student struct {
ID int `json:"id"` // 使用 tag 指定序列化时的键名
Gender string // 默认使用字段名作为键名
name string // 私有字段无法被 json 包访问
}
使用 json.Marshal
进行序列化:
data, err := json.Marshal(s1)
匿名函数
在Go中,匿名函数是一种没有名称的函数,可以被直接赋值给一个变量。这种函数常用于事件处理、回调函数等场景。
getSqrt := func(a float64) float64 {
return math.Sqrt(a) // 计算并返回a的平方根
}
在这个例子中,getSqrt
是一个匿名函数,它接受一个 float64
类型的参数 a
,并返回 a
的平方根。
闭包
闭包是一个函数和其周围状态(词法环境)的组合。在Go中,闭包可以用来创建具有特定状态的函数。
func a() func() int {
i := 0
b := func() int {
i++
fmt.Println(i)
return i
}
return b
}
func main() {
c := a() // c 是一个闭包,它捕获了变量i
c() // 输出 1
c() // 输出 2
c() // 输出 3
d := a() // d 是一个新的闭包,它有自己的变量i
d() // 输出 1,不会输出4
}
在这个例子中,函数 a
返回一个闭包 b
,这个闭包捕获了变量 i
。每次调用 b
时,都会增加 i
的值并打印出来。每次调用 a
都会创建一个新的闭包,它们各自有自己的 i
变量。
延时调用 defer
defer
关键字用于延迟函数的执行,直到包含它的函数即将返回时。defer
可以用于资源清理,如关闭文件、释放锁等。
func main() {
defer fmt.Println("Deferred function called") // 这将在main函数返回前执行
fmt.Println("Main function running")
}
在这个例子中,fmt.Println("Deferred function called")
将在 main
函数返回前被调用。如果有多个 defer
语句,它们将按照后进先出(LIFO)的顺序执行。
异常处理
Go语言没有传统的异常处理机制,而是使用 panic
和 recover
来处理错误。
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in main", r)
}
}()
panic("a problem")
}
在这个例子中,panic("a problem")
抛出了一个错误,defer
语句中的匿名函数捕获了这个错误,并使用 recover
函数恢复了程序的执行。recover
可以捕获 panic
抛出的值,并且只能被 defer
函数调用。
这些代码片段展示了Go语言中匿名函数、闭包、defer
和异常处理的基本用法。希望这些整理和补充对您有所帮助。