一文带你速通Go语言基础语法

写在文章开头

笔者在很早以前就有通过协程并发编程的概念中了解到Go,自此对Go爱不释手,对于Go语言来说,它有着如下的优势:

  1. 上手快:笔者第一次接触的Go的时候,简单搭建一下环境就直接手撸了一个协程的小工具。
  2. 并发异步无痛点:相较于Java而言,Go的几个并发编程的工具简单易上手,并发编程可以说是轻而易举。
  3. 简单而强大:这一点是读耗子前辈的专栏得到的一个观点,它有着C语言的姿态和python的理念,可以说一门简单而强大的编程语言。
  4. 实用的lib库:很多人都说Go非常适合写一个追求性能的小工具,这一点笔者也是非常同意,在笔者日常写Go代码的时候就有这种感觉,Go语言自带的lib库有着很多实用的工具,基本上无需依靠第三方的轮子就可以简单的功能。

所以就想着要专门出一个系列介绍一下Go这门语言,在上一篇文章我们完成了最基础的环境搭建之后,我们就可以正式的开始写Go代码了。 这篇文章算是一篇基本的语法速通的扫盲,通过这篇文章你将会对Go的语法和一些编程习惯有一个初步的了解和掌握。

一文带你速通Go语言基础语法

Hi,我是sharkChili,是个不断在硬核技术上作死的java coder,是CSDN的博客专家,也是开源项目Java Guide的维护者之一,熟悉Java也会一点Go,偶尔也会在C源码边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号:写代码的SharkChili

第一行go代码

以下面这段代码为例,我们介绍以下Go语言的编码基本套路:

  1. 指明运行文件的包为main,只有main包下的文件才会被运行(这一点笔者会在后续的文章中介绍原因)。
  2. 导入需要用到的包,因为我们要输出语句,所以需要导入fmt包(即format包)。
  3. main函数里面Println一段话。
go 复制代码
// 文件中所有其余代码都属于main包
package main

//导入包
import "fmt"

// main方法,程序运行的入口
func main() {
 //用fmt包的Println输出一段话
 fmt.Println("hello world")
}

完成上述编码之后,我们运行程序,即可在中断上得到打印的输出语句:

复制代码
hello world

可以看到当我们需要用到相应的工具就得导入对应的包,然后通过包名.方法即完成方法的调用,与其他语言有所不同,Go语言要导入多个包时需要通过括号包围这些包名,一下面这段代码为例,我们希望打印出2.6向下取整和hello go首字母大写的字符串,那么我们就需要依次导入:

  1. fmt包。
  2. 数学相关的math包。
  3. 字符串操作的strings包。

所以我们的导入包的语法格式如下:

go 复制代码
package main

import (
 "fmt"
 "math"
 "strings"
)

func main() {
 //向下取整
 fmt.Println(math.Floor(2.6))
 //首字母转大写
 fmt.Println(strings.Title("hello go"))
}

完成后我们运行程序,得到下面这段输出:

复制代码
2
Hello Go

变量扫盲

基本类型

任何一门对于变量都会通过类型来决定内存分配和编译优化,Go语言也一样,总的来说,Go语言大抵有以下几种类型:

  1. 数字类型: intint8int16int32int64uintuint8uint16uint32uint64 等,其中int为整型,后面跟着的数字代表位数,例如int8即8位(1个字节)的整型,而uint则无符号整型后面数字的含义一样,默认情况下int的字节数由操作系统决定,例如笔者的操作系统为64位,那么int默认就是64/88个字节
  2. 字符串类型:string
  3. 布尔类型:bool
  4. 复数类型: complex64complex128complex64即复数类型,这有一些数学的概念,例如下面这段complex64 即实部虚部都是32位浮点数,complex128即实部和虚部都是64位浮点数,左边为实部右边为虚部,这里我们就先简单介绍一下complex64
go 复制代码
 // 使用复数类型 complex64
 var z1 complex64 = 3 + 2i
 fmt.Println("Complex number:", z1)
 fmt.Println("Real part:", real(z1))
 fmt.Println("Imaginary part:", imag(z1))

输出结果如下,可以看到打印出来的实部为3,虚部为2:

dart 复制代码
Complex number: (3+2i)
Real part: 3     
Imaginary part: 2

再来看看complex128这个类型:

go 复制代码
func main() {
 // 使用复数类型 complex128
 var z2 complex128 = 4 + 5i
 fmt.Println("Complex number:", z2)
 fmt.Println("Real part:", real(z2))
 fmt.Println("Imaginary part:", imag(z2))
}

对应打印结果是一致的,只不过complex12864位浮点数,精度更高一些:

dart 复制代码
Complex number: (4+5i)
Real part: 4
Imaginary part: 5

字面量与字符串

对于Go语言来说,描述字符的有字符串和字面量,而两者的区别是:

  1. 字面量在Go语言中成为rune,是unicode编码,即用ASCII编码表示,所以在打印时会输出数字。
  2. 字符串声明时通过双引号包围,打印时直接输出字符串。

对此我们给出一段代码示例,分别打印字面量和字符串:

csharp 复制代码
func main() {
 //打印字面量
 fmt.Println('A')
 //打印字符串
 fmt.Println("A")
}

输出结果如下,可以看到rune用数字表示,而字符串输出的就是字符串:

css 复制代码
65
A

获取变量的类型

Go语言的reflect包下提供各种反射的操作,其中TypeOf方法可返回变量类型:

less 复制代码
func main() {
 //获取变量类型
 fmt.Println(reflect.TypeOf(3))
 fmt.Println(reflect.TypeOf(3.14))
 fmt.Println(reflect.TypeOf('A'))
 fmt.Println(reflect.TypeOf("A"))
 fmt.Println(reflect.TypeOf(false))
}

输出结果如下:

go 复制代码
int
float64
int32  
string 
bool  

变量赋值

Go语言对于变量的赋值比较灵活,这里笔者介绍一下最基本的赋值语法,通过var声明变量后,再用等号对变量进行赋值:

dart 复制代码
import (
 "fmt"
)

func main() {
 //声明变量
 var num int
 //赋值
 num = 1
 //使用
 fmt.Println(num)
}

当然go也支持一次性声明多个变量再赋值:

dart 复制代码
import (
 "fmt"
)

func main() {
 //一次声明多变量
 var num, num2 int
 //赋值
 num = 1
 num2 = 2
 //使用
 fmt.Println(num, num2)
}

当然你也可以一次性声明多个变量在进行赋值操作:

go 复制代码
import "fmt"

func main() {
 //声明变量并赋值
 var num = 1
 fmt.Println(num)
 var num2, num3 = 2, 3
 fmt.Println(num2, num3)
}

上文笔者说过,Go之所以灵活是因为变量赋值时可以直接通过:=进行变量赋值,让Go语言再编译时获取变量类型完成内存分配和优化的工作:

go 复制代码
func main() {
 //短变量声明一个int类型
 num := 1
 //打印值
 fmt.Println(num)
 //打印类型
 fmt.Println(reflect.TypeOf(num))
}

对应的输出结果如下,可以看到对应类型打印是int,可以看出Go语言的短变量声明是非常简单且优雅的:

arduino 复制代码
1
int

变量的默认值

go语言的变量默认有值的,例如数字默认为0,布尔默认为false,其他类型同理,这里笔者简单演示一下没有进行任何赋值操作的int和bool类型默认值的打印代码:

csharp 复制代码
func main() {
 //声明变量并赋值
 var num int
 fmt.Println(num)
 var b1, b2 bool
 fmt.Println(b1, b2)
}

可以看到结果和笔者说的一样,整型默认输出0,而bool默认为false

arduino 复制代码
0
false false

类型强转

与其他的编程语言(Java)有所不同,Go语言对不同的精度数字类型计算时不会进行自动的类型升级,所以在进行整数和小数的运算时,我们需要进行一下强转,强转的语法如下即类型(变量):

go 复制代码
func main() {
 //不同类型无法通过编译
 length := 2
 width := 3.2
 //将length强转为float
 lengtnFloat := float64(length)
 fmt.Println(lengtnFloat * width)
}

最终得到正确的计算输出结果:

复制代码
6.4

当然如果带小数的类型转为int时,还是需要考虑精度丢失问题,这里笔者就不输出演示了:

go 复制代码
import "fmt"

func main() {
 //强转精度丢失问题
 width := 3.6
 fmt.Println(int(width))

}

条件分支

if语法

JavaC这类编程语言不同,Go的if语句比较清爽没有括号,直接在if后面带上条件即可:

go 复制代码
func main() {
 num := 8
 
 if num < 0 {
  fmt.Println("num < 0")
 } else if num < 5 {
  fmt.Println("num < 5")
 } else {
  fmt.Println("num > 5")
 }

}

switch判断

和其他编程语言不同的是,Go语言中switch是非常常用的判断,它时常和channel进行配合控制协程调度,这一点笔者会在后续的实际案例中演示,这里先介绍一下switch的语法格式,可以看到go语言的switch也是很清爽的,无需添加break即可完成分支:

go 复制代码
func main() {
 num := 3
 
 switch num {
 case 1:
  fmt.Println("num = 1")
 case 2:
  fmt.Println("num = 2")
 case 3:
  fmt.Println("num = 3")
 }

}

循环分支

与其他语言相比Go语言没有while和do-while这种循环,取而代之的都说for循环,下面这个例子我们可以同义转换为while(i<10)这种编程习惯:

css 复制代码
func main() {

 i := 0
 sum := 0
 for i < 10 {
  sum += i
  i++
 }

 fmt.Println(sum)
}

对于那些习惯了Java或者C的开发来说,Go语言的无限循环语法可能会让你感到别扭,语言如下所示,即不带任何条件的for:

csharp 复制代码
func main() {

 for {
  fmt.Println("无限循环")
 }
}

唯一让读者感到亲切的应该就是下面这种fori格式的有界循环了,这里笔者就不多做赘述了:

css 复制代码
func main() {

 sum := 0
 for i := 0; i < 10; i++ {
  sum += i
 }

 fmt.Println(sum)
}

函数

基本语法

函数的基本语法如下,我们希望传入两个int的值得到一个返回int的函数,Go语言的语法格式如下:

go 复制代码
func main() {
 fmt.Println(add(1, 2))
}

func add(num1 int, num2 int) int {
 c := num1 + num2
 return c
}

不过有时候也可以这样写,看起来没有精简到哪里去,对于笔者而言这种语法基本很少用,读者了解一下即可:

csharp 复制代码
func main() {

 fmt.Println(add(1, 2))
}


func add(num1 int, num2 int) (c int) {
 c = num1 + num2
 return c
}

多返回值

多返回值算是Go语言让读者感到惊艳的地方了,很多编程语言为了得到多返回值,都会采用传入引用进行复制或者像C这种传入指针的操作,非常不优雅,与之相比,Go语言就比较方便了,只需用括号声明多返回值的列表,然后按需返回多个返回值即可:

go 复制代码
func main() {
 sum, str := add(1, 2)
 fmt.Println(sum)
 fmt.Println(str)
}

// add 返回int和string类型的函数
func add(num1 int, num2 int) (int, string) {
 c := num1 + num2
 return c, "计算成功"
}

对应的输出结果如下:

复制代码
3
计算成功

Go语言常见命令

一般情况下,我们现在编写Go语言程序都会采用Goland,通过点击界面运行指令,所以对于下面这些常见命令我们需要简单了解一下,便于后续在Linux上操作以及了解Goland的各个界面中提供的指令的含义:

go 复制代码
1. go build 将源代码文件编译为二进制文件
2. go run 编译并运行程序,而不保存可执行文件
3. go fmt 使用GO标准格式重新格式化源文件
4. go version 显示当前Go版本号

小结

这篇Go大基础扫盲的篇章到此为止,希望读者可以通过根据笔者的文章简单实用一下Go语言,笔者会在后续的系列中演示Go各个常用的包及其源码级的原理解析。

我是sharkchiliCSDN Java 领域博客专家开源项目---JavaGuide contributor ,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号:写代码的SharkChili和笔者的交流群进行深入交流。

参考

Head First Go语言程序设计:book.douban.com/subject/352... Go语言实战:book.douban.com/subject/270...

本文使用 markdown.com.cn 排版

相关推荐
幽络源小助理11 小时前
springboot校园车辆管理系统源码 – SpringBoot+Vue项目免费下载 | 幽络源
vue.js·spring boot·后端
刀法如飞11 小时前
一款开箱即用的Spring Boot 4 DDD工程脚手架
java·后端·架构
uzong11 小时前
后端系统设计文档模板
后端
幽络源小助理12 小时前
SpringBoot+Vue车票管理系统源码下载 – 幽络源免费项目实战代码
vue.js·spring boot·后端
uzong12 小时前
软件架构指南 Software Architecture Guide
后端
又是忙碌的一天12 小时前
SpringBoot 创建及登录、拦截器
java·spring boot·后端
勇哥java实战分享13 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要13 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn089513 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪13 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端