【编程语言】Golang入门

目录

一、为什么选择 Golang

二、环境搭建

Windows 系统

MacOS 系统

Linux 系统

三、基础语法

(一)变量与数据类型

(二)运算符

(三)流程控制

1. 条件语句

2. 循环语句

四、函数与结构体

(一)函数

(二)结构体

五、实战项目:简易命令行工具

(一)项目需求分析

(二)代码实现

(三)运行与测试

六、学习资源推荐


一、为什么选择 Golang

在当今数字化时代,Golang 异军突起,在云计算、容器编排、网络编程等领域都有广泛应用 ,像大家熟知的 Kubernetes,作为容器编排领域的佼佼者,其核心组件和大部分插件都是用 Golang 编写的;还有知名的开源容器管理平台 Docker,也依赖于 Golang 的高并发处理能力,能够在大规模集群中高效地管理和调度容器。这些优秀的项目无一不在彰显着 Golang 高性能、高并发的优势。

就我自身而言,我在开发一个高并发的网络服务项目时,一开始选用了传统的编程语言,开发过程中频繁遇到线程资源消耗过大、并发控制复杂等问题,项目推进举步维艰。后来接触到 Golang,它那简洁的语法和强大的并发处理机制,让我眼前一亮。使用 Golang 重构项目后,不仅代码量大幅减少,程序的运行效率和稳定性更是得到了质的飞跃。从那时起,我便深深被 Golang 的魅力所吸引,开启了深入学习 Golang 的旅程。

二、环境搭建

“工欲善其事,必先利其器”,在开启 Golang 学习之旅前,我们得先把开发环境搭建好。获取 Golang 安装包的途径有很多,官网(https://golang.org/dl/ )自然是最权威的下载渠道 ,不过由于网络原因,国内的小伙伴访问可能不太顺畅,这时就可以考虑一些国内的镜像站点,比如 Go 语言中文社区(Go下载 – Go语言中文网 – Golang中文社区 ),不仅下载速度快,资源也很靠谱。

下面就为大家详细介绍不同操作系统下的安装步骤:

Windows 系统

下载安装包:在浏览器中打开上述下载渠道,找到 Windows 版本的 Golang 安装包,一般是.msi 后缀的文件,根据你的系统是 32 位还是 64 位,选择对应的版本下载。

安装 Golang:下载完成后,双击安装包,进入安装向导界面,一路点击 “Next”,安装过程中可以选择安装路径,建议新手保持默认路径,这样后续配置环境变量会更方便。

配置环境变量:安装完成后,还需要将 Golang 的安装路径添加到系统的环境变量中。具体操作如下:右键点击 “此电脑”,选择 “属性”,在弹出的窗口中点击 “高级系统设置”,然后在 “系统属性” 窗口中点击 “环境变量”。在 “系统变量” 中找到 “Path” 变量,点击 “编辑”,在弹出的编辑环境变量窗口中,点击 “新建”,添加 Golang 的安装路径下的 bin 目录,比如 “C:Goin”(如果安装时选择了其他路径,请根据实际情况修改),添加完成后,一路点击 “确定” 保存设置。

验证安装:按下 “Win+R” 组合键,打开运行对话框,输入 “cmd”,回车打开命令提示符窗口,在窗口中输入 “go version”,如果成功输出 Golang 的版本号,如 “go version go1.21.0 windows/amd64”,则说明安装成功。

MacOS 系统

下载安装包:前往 Golang 官网或国内镜像站点,下载适用于 MacOS 的.pkg 后缀安装包。

安装 Golang:双击下载好的安装包,按照安装向导的提示一步步完成安装,安装过程同样简单,基本上一路点击 “继续” 即可。

配置环境变量:安装完成后,打开终端,输入以下命令打开.zshrc 文件(如果使用的是 bash,就打开.bash_profile 文件):nano ~/.zshrc ,在打开的文件末尾添加以下两行代码:


export GOPATH=$HOME/go

export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

添加完成后,按下 “Ctrl+X”,再按下 “Y”,最后按下 “Enter” 保存并退出。然后输入source ~/.zshrc使配置生效。

4. 验证安装:在终端中输入 “go version”,若输出 Golang 版本号,说明安装无误。

Linux 系统

下载安装包:在终端中使用 wget 命令下载 Golang 安装包,比如下载最新版本的命令可能是wget https://dl.google.com/go/go1.21.4.linux-amd64.tar.gz ,请根据实际的最新版本链接进行替换。

解压安装包:下载完成后,使用以下命令将安装包解压到 /usr/local 目录下:sudo tar -C /usr/local -xzf go1.21.4.linux-amd64.tar.gz (文件名需根据实际下载的版本修改)。

配置环境变量:编辑~/.profile 或~/.bashrc 文件,在文件末尾添加export PATH=$PATH:/usr/local/go/bin ,然后输入source ~/.profile(如果编辑的是.bashrc 文件,就输入source ~/.bashrc)使配置生效。

验证安装:在终端输入 “go version”,若显示版本号,恭喜你,安装成功了。

当看到 “go version” 命令输出对应的 Golang 版本信息时,就代表我们已经成功搭建好了 Golang 开发环境,可以开启代码编写之旅啦!

三、基础语法

掌握 Golang 的基础语法,就好比掌握了一门语言的词汇和基本句型,是与计算机顺畅 “交流” 的关键。接下来,我将带大家深入学习 Golang 的基础语法。

(一)变量与数据类型

在 Golang 中,变量是存储数据的载体,就像一个个小盒子,每个盒子都有自己的名字和类型,用来存放不同的数据。变量的声明方式有多种,比如使用var关键字显式声明变量类型,var num int ,这就声明了一个名为num的整型变量;也可以让编译器自动推断变量类型,var num = 10 ,这里编译器会根据值10推断num为整型;还有更简洁的短变量声明方式num := 10 ,这种方式只能在函数内部使用 ,并且会自动推断变量类型。

Golang 中的数据类型丰富多样,常见的有整型、浮点型、布尔型、字符串等 。整型用于存储整数,像int类型可以根据系统自动适配 32 位或 64 位,还有int8、int16、int32、int64等指定长度的整型 ,分别表示 8 位、16 位、32 位、64 位的有符号整数,与之对应的还有无符号整型uint8、uint16、uint32、uint64 。浮点型用于存储小数,float32表示 32 位浮点数,float64表示 64 位浮点数,在实际应用中,如果对精度要求较高,建议使用float64 。布尔型只有两个值true和false ,常用于逻辑判断。字符串则用于存储文本,用双引号”括起来,比如var str string = “Hello, Golang” 。下面通过一段简单的代码来展示不同类型变量的使用:


package main

import "fmt"

func main() {

// 整型变量

var age int = 20

fmt.Printf("age的类型是%T,值是%d
", age, age)

// 浮点型变量

var price float64 = 19.99

fmt.Printf("price的类型是%T,值是%f
", price, price)

// 布尔型变量

var isStudent bool = true

fmt.Printf("isStudent的类型是%T,值是%v
", isStudent, isStudent)

// 字符串变量

var name string = "张三"

fmt.Printf("name的类型是%T,值是%s
", name, name)

}

运行上述代码,输出结果如下:


age的类型是int,值是20

price的类型是float64,值是19.990000

isStudent的类型是bool,值是true

name的类型是string,值是张三

(二)运算符

运算符是对变量或值进行操作的符号,就像数学中的加、减、乘、除符号一样,Golang 中的运算符也有很多种,包括算术运算符、比较运算符、逻辑运算符、赋值运算符等。

算术运算符用于基本的数学运算,如加法(+)、减法(-)、乘法(*)、除法(/)、取余(%) ,还有自增(++)和自减(–)运算符 。下面是一些算术运算符的使用示例:


package main

import "fmt"

func main() {

a := 10

b := 3

// 加法

sum := a + b

fmt.Printf("%d + %d = %d
", a, b, sum)

// 减法

diff := a - b

fmt.Printf("%d - %d = %d
", a, b, diff)

// 乘法

product := a * b

fmt.Printf("%d * %d = %d
", a, b, product)

// 除法

quotient := a / b

fmt.Printf("%d / %d = %d
", a, b, quotient)

// 取余

remainder := a % b

fmt.Printf("%d %% %d = %d
", a, b, remainder)

// 自增

a++

fmt.Printf("a自增后的值是%d
", a)

// 自减

b--

fmt.Printf("b自减后的值是%d
", b)

}

运行结果:


10 + 3 = 13

10 - 3 = 7

10 * 3 = 30

10 / 3 = 3

10 % 3 = 1

a自增后的值是11

b自减后的值是2

比较运算符用于比较两个值的大小或是否相等,结果是布尔型(true或false) ,常见的比较运算符有等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=) 。示例代码如下:


package main

import "fmt"

func main() {

a := 10

b := 5

fmt.Printf("%d == %d 结果是%v
", a, b, a == b)

fmt.Printf("%d != %d 结果是%v
", a, b, a != b)

fmt.Printf("%d > %d 结果是%v
", a, b, a > b)

fmt.Printf("%d < %d 结果是%v
", a, b, a < b)

fmt.Printf("%d >= %d 结果是%v
", a, b, a >= b)

fmt.Printf("%d <= %d 结果是%v
", a, b, a <= b)

}

运行结果:


10 == 5 结果是false

10 != 5 结果是true

10 > 5 结果是true

10 < 5 结果是false

10 >= 5 结果是true

10 <= 5 结果是false

逻辑运算符用于组合多个布尔表达式,进行逻辑判断,主要有逻辑与(&&)、逻辑或(||)、逻辑非(!) 。下面是逻辑运算符的使用示例:


package main

import "fmt"

func main() {

a := true

b := false

fmt.Printf("a && b 结果是%v
", a && b)

fmt.Printf("a || b 结果是%v
", a || b)

fmt.Printf("!a 结果是%v
",!a)

}

运行结果:


a && b 结果是false

a || b 结果是true

!a 结果是false

赋值运算符用于将一个值赋给一个变量,最基本的赋值运算符是= ,还有复合赋值运算符,如+=、-=、*=、/=、%=等 。示例代码如下:


package main

import "fmt"

func main() {

a := 10

// 基本赋值

a = 20

fmt.Printf("a赋值后的值是%d
", a)

// 复合赋值

a += 5

fmt.Printf("a += 5后的值是%d
", a)

a -= 3

fmt.Printf("a -= 3后的值是%d
", a)

a *= 2

fmt.Printf("a *= 2后的值是%d
", a)

a /= 4

fmt.Printf("a /= 4后的值是%d
", a)

a %= 3

fmt.Printf("a %= 3后的值是%d
", a)

}

运行结果:


a赋值后的值是20

a += 5后的值是25

a -= 3后的值是22

a *= 2后的值是44

a /= 4后的值是11

a %= 3后的值是2

(三)流程控制

流程控制语句是编程语言的 “方向盘”,它决定了程序的执行顺序和路径,让程序能够根据不同的条件和需求,执行不同的代码块,实现各种复杂的逻辑功能。接下来,我们就来学习 Golang 中重要的流程控制语句。

1. 条件语句

Golang 中的条件语句主要有if语句和switch语句 ,它们就像现实生活中的决策工具,根据不同的条件做出不同的选择。

if语句用于根据条件判断来执行不同的代码块,语法结构如下:


if 条件表达式 {

// 条件为true时执行的代码

} else {

// 条件为false时执行的代码

}

条件表达式可以是比较表达式、逻辑表达式等,返回一个布尔值。if语句还支持在条件表达式之前初始化变量,使用分号;分隔 ,比如if num := 10; num > 5 { fmt.Println(num, “大于5”) } 。下面通过一个成绩评级的案例来展示if语句的应用:


package main

import "fmt"

func main() {

score := 85

if score >= 90 {

fmt.Println("成绩评级为:A")

} else if score >= 80 {

fmt.Println("成绩评级为:B")

} else if score >= 60 {

fmt.Println("成绩评级为:C")

} else {

fmt.Println("成绩评级为:D")

}

}

运行上述代码,输出结果为:成绩评级为:B

switch语句用于根据一个变量的值,从多个分支中选择一个执行,语法结构如下:


switch 变量 {

case 值1:

// 变量等于值1时执行的代码

case 值2:

// 变量等于值2时执行的代码

default:

// 变量不等于任何case值时执行的代码

}

switch语句还支持多个值匹配,用逗号分隔 ,比如case 值1, 值2, 值3: ,也支持省略switch后面的变量,直接在case中使用表达式,此时相当于switch true 。下面是一个根据不同条件执行不同操作的案例:


package main

import "fmt"

func main() {

day := 3

switch day {

case 1:

fmt.Println("今天是星期一,开始新一周的工作")

case 2:

fmt.Println("今天是星期二,工作继续加油")

case 3:

fmt.Println("今天是星期三,已经过去一半啦")

case 4:

fmt.Println("今天是星期四,胜利就在前方")

case 5:

fmt.Println("今天是星期五,期待周末")

case 6, 7:

fmt.Println("今天是周末,好好放松")

default:

fmt.Println("输入的不是有效的星期数")

}

}

运行上述代码,输出结果为:今天是星期三,已经过去一半啦

2. 循环语句

循环语句用于重复执行一段代码,直到满足特定条件为止,Golang 中只有for循环这一种循环语句,但它的形式非常灵活,可以实现其他语言中for循环、while循环和do-while循环的功能。

for循环的基本形式如下:


for 初始化语句; 条件表达式; 后置语句 {

// 循环体

}

初始化语句在循环开始前执行一次,用于初始化循环变量;条件表达式在每次循环开始时判断,如果为true,则执行循环体,否则结束循环;后置语句在每次循环结束后执行 ,通常用于更新循环变量。例如,计算 1 到 100 的和:


package main

import "fmt"

func main() {

sum := 0

for i := 1; i <= 100; i++ {

sum += i

}

fmt.Println("1到100的和是", sum)

}

运行上述代码,输出结果为:1 到 100 的和是 5050

for循环还可以省略初始化语句、条件表达式和后置语句中的一个或多个 ,如果省略条件表达式,就会形成无限循环,需要在循环体内使用break语句来跳出循环 。比如实现一个while循环的功能:


package main

import "fmt"

func main() {

i := 1

for i <= 5 {

fmt.Println(i)

i++

}

}

运行上述代码,会依次输出 1 到 5。

for循环还有一种特殊的形式for-range ,用于遍历数组、切片、字符串、映射和通道等数据结构,它会返回每个元素的索引和值 。例如,遍历一个数组:


package main

import "fmt"

func main() {

numbers := [5]int{1, 2, 3, 4, 5}

for index, value := range numbers {

fmt.Printf("索引 %d 对应的值是 %d
", index, value)

}

}

运行上述代码,会输出数组中每个元素的索引和值。

四、函数与结构体

(一)函数

函数是 Golang 代码的基本组成部分,是实现模块化编程的重要工具,就像是一个个功能明确的 “小机器”,接收输入(参数),经过一系列处理后,输出结果(返回值) 。

函数定义的基本语法如下:


func 函数名(参数列表) (返回值列表) {

// 函数体,实现具体功能的代码块

return 返回值

}

其中,func是定义函数的关键字,函数名要遵循命名规范,一般采用驼峰命名法,做到见名知意;参数列表用于接收外部传入的数据,参数类型在参数名之后,多个参数之间用逗号分隔 ,比如(a int, b string) ;返回值列表指定函数返回的数据类型 ,可以返回多个值,用括号括起来,若不返回值,可省略括号。例如,一个简单的加法函数:


func add(a int, b int) int {

return a + b

}

这个函数名为add,接收两个int类型的参数a和b ,返回它们的和,也是int类型。当多个参数类型相同时,可以简写,如func add(a, b int) int 。

调用函数也很简单,直接使用函数名,并传入对应的参数即可。例如:


package main

import "fmt"

func add(a, b int) int {

return a + b

}

func main() {

result := add(3, 5)

fmt.Println("3和5的和是", result)

}

在上述代码中,在main函数里调用了add函数,传入参数 3 和 5,将返回的结果赋值给result变量,最后打印输出。

接下来,通过一些实际案例来感受函数的强大功能。比如计算圆的面积,圆的面积公式为(S=pi r^2) ,我们可以定义一个函数来实现:


package main

import (

"fmt"

"math"

)

func circleArea(radius float64) float64 {

return math.Pi * radius * radius

}

func main() {

radius := 5.0

area := circleArea(radius)

fmt.Printf("半径为%.2f的圆的面积是%.2f
", radius, area)

}

运行结果:


半径为5.00的圆的面积是78.54

再比如判断一个数是否为素数,素数是指在大于 1 的自然数中,除了 1 和它自身外,不能被其他自然数整除的数。实现代码如下:


package main

import (

"fmt"

"math"

)

func isPrime(num int) bool {

if num <= 1 {

return false

}

for i := 2; i <= int(math.Sqrt(float64(num))); i++ {

if num%i == 0 {

return false

}

}

return true

}

func main() {

number := 17

if isPrime(number) {

fmt.Println(number, "是素数")

} else {

fmt.Println(number, "不是素数")

}

}

运行结果:


17 是素数

(二)结构体

在实际编程中,我们常常需要表示一些复杂的数据,比如一个学生的信息,包含姓名、年龄、成绩等,这些信息的数据类型各不相同,单纯的基本数据类型无法满足需求,这时就需要用到结构体。结构体是一种复合数据类型,它可以将不同类型的数据组合在一起,形成一个新的自定义类型,就像是一个 “数据集合体”,把相关的数据组织在一起,方便管理和操作。

结构体的定义语法如下:


type 结构体名 struct {

字段名1 字段类型1

字段名2 字段类型2

// 可以有多个字段

}

例如,定义一个学生信息的结构体:


type Student struct {

Name string

Age int

Score float64

}

这里定义了一个名为Student的结构体,它包含三个字段,分别是Name(字符串类型,表示姓名)、Age(整型,表示年龄)和Score(浮点型,表示成绩) 。

初始化结构体有多种方式,常见的有以下几种:

完整初始化:使用键值对的方式,明确指定每个字段的值。


student1 := Student{

Name: "张三",

Age: 20,

Score: 85.5,

}

简写初始化:按照结构体定义字段的顺序,直接提供字段值。


student2 := Student{"李四", 21, 90.0}

部分初始化:只初始化部分字段,未初始化的字段会使用零值(数值类型为 0,布尔类型为 false,字符串类型为空字符串等) 。


student3 := Student{Name: "王五"}

先声明再赋值:先声明一个结构体变量,然后再逐个为字段赋值。


var student4 Student

student4.Name = "赵六"

student4.Age = 22

student4.Score = 78.0

访问结构体的成员(字段)使用点号(.)操作符,例如:


package main

import "fmt"

type Student struct {

Name string

Age int

Score float64

}

func main() {

student := Student{

Name: "张三",

Age: 20,

Score: 85.5,

}

fmt.Println("学生姓名:", student.Name)

fmt.Println("学生年龄:", student.Age)

fmt.Println("学生成绩:", student.Score)

}

运行结果:


学生姓名: 张三

学生年龄: 20

学生成绩: 85.5

通过结构体,我们可以将相关的数据紧密地结合在一起,让代码的结构更加清晰,逻辑更加严谨,为后续的编程工作提供了极大的便利。

五、实战项目:简易命令行工具

(一)项目需求分析

我们要打造的这个简易命令行工具,具备两大实用功能:文件操作和简单计算。在文件操作方面,它能够实现文件的读取、写入以及复制 。比如,当你需要查看某个文本文件的内容时,通过命令行参数指定文件名,工具就能读取文件并将内容输出到控制台;要是你想创建一个新的文本文件并写入一些信息,或者把一个文件的内容复制到另一个文件中,这个工具也能轻松搞定。在简单计算功能上,它支持加、减、乘、除四则运算 。你可以在命令行中输入两个数字以及对应的运算符,工具就会计算出结果。这个工具就像是一个多功能的小助手,能在日常的开发和系统管理中,帮我们快速完成一些常见的任务,提高工作效率。

(二)代码实现


package main

import (

"flag"

"fmt"

"io/ioutil"

"log"

"os"

"strconv"

)

// 定义文件操作相关变量

var (

readFile string

writeFile string

copySource string

copyTarget string

)

// 定义计算相关变量

var (

num1 float64

num2 float64

operator string

)

func init() {

// 文件操作参数定义

flag.StringVar(&readFile, "read", "", "读取文件")

flag.StringVar(&writeFile, "write", "", "写入文件,格式为'write -write filename content'")

flag.StringVar(&copySource, "copy-source", "", "复制源文件")

flag.StringVar(&copyTarget, "copy-target", "", "复制目标文件")

// 计算参数定义

flag.Float64Var(&num1, "num1", 0, "第一个数字")

flag.Float64Var(&num2, "num2", 0, "第二个数字")

flag.StringVar(&operator, "op", "", "运算符,支持+、-、*、/")

}

func main() {

flag.Parse()

// 文件操作部分

if readFile != "" {

readFileContent(readFile)

}

if writeFile != "" && flag.NArg() > 0 {

content := flag.Arg(0)

writeToFile(writeFile, content)

}

if copySource != "" && copyTarget != "" {

copyFile(copySource, copyTarget)

}

// 计算部分

if operator != "" && num1 != 0 && num2 != 0 {

calculate(num1, num2, operator)

}

}

// 读取文件内容

func readFileContent(filename string) {

data, err := ioutil.ReadFile(filename)

if err != nil {

log.Fatalf("读取文件错误: %v", err)

}

fmt.Println(string(data))

}

// 写入文件

func writeToFile(filename, content string) {

err := ioutil.WriteFile(filename, []byte(content), 0644)

if err != nil {

log.Fatalf("写入文件错误: %v", err)

}

fmt.Printf("成功写入内容到 %s
", filename)

}

// 复制文件

func copyFile(source, target string) {

data, err := ioutil.ReadFile(source)

if err != nil {

log.Fatalf("读取源文件错误: %v", err)

}

err = ioutil.WriteFile(target, data, 0644)

if err != nil {

log.Fatalf("写入目标文件错误: %v", err)

}

fmt.Printf("成功将 %s 复制到 %s
", source, target)

}

// 执行计算

func calculate(a, b float64, op string) {

var result float64

switch op {

case "+":

result = a + b

case "-":

result = a - b

case "*":

result = a * b

case "/":

if b == 0 {

log.Fatal("除数不能为0")

}

result = a / b

default:

log.Fatal("不支持的运算符")

}

fmt.Printf("计算结果: %.2f %s %.2f = %.2f
", a, op, b, result)

}

代码解释:

初始化部分:使用flag包定义命令行参数,flag.StringVar用于定义字符串类型的参数,flag.Float64Var用于定义浮点型参数 ,并设置了参数的默认值和说明。

main函数:调用flag.Parse()解析命令行参数,然后根据不同的参数执行相应的功能。如果readFile参数有值,调用readFileContent函数读取文件;如果writeFile参数有值且后面有传入的内容,调用writeToFile函数写入文件;如果copySource和copyTarget参数都有值,调用copyFile函数复制文件;如果operator、num1和num2参数都有值,调用calculate函数进行计算。

文件操作函数:readFileContent函数使用ioutil.ReadFile读取文件内容,并将其转换为字符串输出;writeToFile函数使用ioutil.WriteFile将传入的内容写入指定文件;copyFile函数先读取源文件内容,再将内容写入目标文件,实现文件复制。

计算函数:calculate函数根据传入的运算符,对两个数字进行相应的加、减、乘、除运算,若除数为 0 或遇到不支持的运算符,会记录错误并终止程序。

(三)运行与测试

运行代码:在命令行中进入代码所在目录,使用go build命令编译代码,会生成一个可执行文件(Windows 下是.exe 后缀,Linux 和 MacOS 下没有后缀) 。例如,代码文件名为main.go,则执行go build main.go 。编译成功后,运行可执行文件并传入相应参数来测试工具功能。

文件读取:运行./main -read test.txt (假设要读取的文件名为 test.txt),如果文件存在且可读,会输出文件内容。

文件写入:运行./main -write new.txt “这是写入的内容” ,会在当前目录下创建一个名为 new.txt 的文件,并将 “这是写入的内容” 写入文件,然后输出 “成功写入内容到 new.txt” 。

文件复制:运行./main -copy-source source.txt -copy-target target.txt ,会将 source.txt 的内容复制到 target.txt,如果复制成功,会输出 “成功将 source.txt 复制到 target.txt” 。

简单计算:运行./main -num1 5 -num2 3 -op + ,会输出 “计算结果: 5.00 + 3.00 = 8.00” 。

可能出现的问题及解决方法

文件不存在:在进行文件读取、复制或写入时,如果文件不存在,会报相应的错误。例如读取文件时,会输出 “读取文件错误: open test.txt: no such file or directory” ,此时需要检查文件名和路径是否正确。

权限不足:在写入或复制文件时,如果没有足够的权限,会报权限错误。比如 “写入文件错误: open new.txt: permission denied” ,这时需要确认当前用户对目标文件或目录是否有写入权限,可通过修改文件权限或使用管理员权限运行程序来解决。

参数错误:如果输入的命令行参数不正确,比如计算时忘记输入运算符,会导致程序无法正确执行。此时需要仔细检查参数的输入格式,可参考代码中init函数里对参数的定义和说明。

六、学习资源推荐

学习 Golang 的道路上,丰富优质的学习资源能让我们事半功倍。在这里,我给大家推荐一些我在学习过程中觉得非常实用的资源。

官方文档:Golang 的官方文档(Documentation – The Go Programming Language )无疑是最权威、最全面的学习资料,它涵盖了从入门到高级的各种知识点,无论是语法详解、标准库的使用,还是最佳实践,都能在官方文档中找到详细的介绍 。而且,官方文档会随着 Golang 版本的更新及时同步,确保我们学到的都是最新、最准确的知识。

书籍

《Go 语言圣经》:这本书堪称 Golang 学习的经典之作,由 Go 语言团队精心打造,全面且深入地讲解了 Golang 的语法、特性以及实际应用,书中配备了大量清晰的代码示例和丰富的练习题,非常适合初学者夯实基础。

《Go 程序设计语言》:同样是极具价值的一本学习宝典,它从基础到高级,系统地剖析了 Golang 的各个方面,作者凭借深厚的专业知识和丰富的实践经验,用简洁易懂的语言将复杂的概念阐述得明明白白 ,是深入学习 Golang 的得力助手。

《Go 语言实战》:以项目为导向,通过一个个实际案例,手把手教你如何在实战中运用 Golang 解决问题,让你在实践中快速积累经验,掌握开发技巧,提升编程能力。

在线教程

菜鸟教程(Go 语言教程 | 菜鸟教程:对新手非常友好,教程内容通俗易懂,循序渐进,从基本语法到进阶应用,都有详细的讲解和示例代码,还提供了在线编程环境,方便随时动手实践。

Go by Example(Go by Example 中文版:收集了大量的 Golang 小示例,每个示例都聚焦一个特定的知识点,简洁明了,能帮助我们快速理解和掌握 Golang 的各种特性,是学习过程中的好帮手。

优质博客

Go 语言中文网(首页 – Go语言中文网 – Golang中文社区:作为国内最大的 Go 语言中文社区,这里汇聚了众多 Golang 爱好者和开发者,不仅有丰富的学习资料、技术文章,还有活跃的交流论坛,遇到问题时,在这里能得到大家的帮助和建议 。

极客兔兔(极客兔兔:博主分享了很多关于 Golang 的深入见解和实战经验,文章深入浅出,从底层原理到实际应用场景,都有精彩的剖析,对提升我们的技术水平很有帮助。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容