前言
这次就要正式进入Go语言
的学习之旅了。Go语言系列:Go从哪里来,Go将去哪里?和Go语言系列:如何搭建Go语言开发环境?分别介绍了Go语言
的起源、现状和开发环境的搭建。那既然迈出了第一步,就要去闯出一片天地出来。所以,想要入坑Go语言
的小伙伴赶紧上车,让我们一起去探寻GO语言
的神秘之处吧
这篇文章只是Go语言
入门的第2
篇文章,所以本文并不会对一些语法使用进行深挖。只会停留在“怎么用”
的层面,至于“为什么是这样”
,就不会在文章中去过深地赘述。毕竟我也是刚入坑,你硬是要问我为什么,那我也不知道,只有深入了解Go语言
之后才会有答案的。
Go语言基本的语法
下面就开始进入Go语言
的基本语法学习啦~
一、变量
编程语言中最基本的就是变量,变量是用来存储各种类型数据的抽象概念。Go语言
中不同类型的变量,需要先声明才能被使用。
1.1 声明变量
1.1.1 标准格式
Go
语言中声明变量以var
关键字开头,变量名放中间,变量类型放在最后。如下:
var 变量名 变量类型
复制代码
1.1.2 批量格式
如果觉得每次在多个变量前面都要定义var
非常繁琐,可以通过var
和括号来批量声明。如下:
var (
a int
b string
c bool
)
复制代码
注意:Go
语言中不需要用分号结尾,除非多个语句或声明出现在同一行;字符串必须是双引号,单行注释是//
,多行注释是/**/
1.2 初始化与定义变量
变量声明好了,那就可以对其进行初始化。在Go语言中,初始化变量有如下几种方法:
1.2.1 标准格式
var 变量名 变量类型 = 变量值
复制代码
举个例:
var a int = 18 // 初始化一个整数,变量名为a,初始值为18的变量
复制代码
1.2.2 编译器推导类型
编译器推导类型顾名思义就是在没有给变量定义类型时,编译器会自行根据等号右边的变量值来推断变量的类型。如下:
var a = 18
复制代码
1.2.3 短变量声明与初始化
短变量声明其实就是省略var
的写法,如下:
a := 18
复制代码
注意: 因为使用了 :=
, 而不是赋值的 =
, 这就限制了等号左边的变量名必须是没有定义过的变量名,否则将会发生编译错误。
举个例:
var a int // 声明一个整型a变量
a := 18 // 再次声明与赋值
复制代码
编译的时候就会报错,如下:
no new variables on left side of := // :=左边的变量已经被声明了
复制代码
1.3 多变量同时赋值
多变量同时赋值的场景主要来源于需要交换两个变量值的需求,传统的做法就是再定义一个临时变量来做中转;但是在Go
语言中就可以利用多重赋值的特性来实现,如下:
var a int = 100
var b int = 200
a, b = b, a
fmt.Println(a, b)
复制代码
运行代码得到如下结果:
200 100
复制代码
1.4 匿名变量
匿名变量就是一个没有名字的变量,使用下划线_
来表示。
假设GetName()
函数的定义如下,它返回3
个值,分别为firstName
、lastName
和nickName
:
func GetName() (firstName, lastName, nickName) {
return "Kobe", "Bryant", "Mamba"
}
复制代码
若只想获得firstName
,则函数调用语句可以用如下方式编写:
firstName, _, _ := GetName()
复制代码
注意:匿名变量不占用内存,不分配内存;匿名变量与匿名变量之间也不会因为多次的声明而无法使用。
二、基础数据类型
Go
语言中的基础数据类型包含:整型、浮点型、布尔型、字符串、字符等。下面就来挨着介绍这几种基础的数据类型。
2.1 整型
在Go
语言中,整型分为以下两个大类:
- 有符号类型,按长度分为:
int8
、int16
、int32
、int64
- 无符号类型,与上对应为:
uint8
、uint16
、uint32
、uint64
看了上述的类型,是不是觉得这也太繁琐了点,定义一个整型变量居然如此花里胡哨,那有没有简便的方法呢?有!那就是直接使用int
和uint
,自己根据平台cpu
机器字节大小来调整长度。
最后,还有一种无符号的整数类型 uintptr
,它没有指定具体的 bit
大小但是足以容纳指针。uintptr
类型只有在底层编程时才需要,特别是Go
语言和C
语言函数库或操作系统接口相交互的地方。
2.2 浮点型
Go
语言中提供了2
种精度浮点型float32
和float64
。这2
种浮点型数据格式遵循IEEE754
浮点数国际标准,该浮点数规范被所有现代的CPU
支持。
浮点型Float32
:即单精度,存储占用4
个字节,也即4*8=32
位,其中1
位用来符号,8
位用来指数,剩下的23
位表示尾数。
浮点型Float64
:即双精度,存储占用8
个字节,也即8*8=64
位,其中1
位用来符号,11
位用来指数,剩下的52
位表示尾数。
float32
的浮点数最大值约为3.4e38
,最小值为1.4e-45
;float64
的浮点数最大值约为1.8e308
,最小值为4.9e-324
。
一个float32
类型的浮点数可以提供大约6
个十进制数的精度,而float64
则可以提供约15
个十进制数的精度;通常应该优先使用float64
类型,因为float32
类型的累计计算误差很容易扩散,并且float32
能精确表示的正整数并不是很大(注意:因为float32
的有效bit
位只有23
个,其它的bit
位用于指数和符号;当整数大于23bit
能表达的范围时,float32
的表示将出现误差)。
浮点数常量的表示:
-小数点前数字可省略:.234
-小数点后数字可省略:23.
-科学计数法:2e23
, 4E23
。(非常大或者非常小的值建议使用此方式)
注意:NaN
,表示科学上无意义的运算结果,如0/0
,sqrt(-1)
,通过match.IsNaN()
函数判断一个变量或表达式的值是否为NaN
。
最后,Go
语言中通过Printf
函数打印浮点数时,可以使用**%f**
来控制保留几位小数,如下:
package main
import (
"fmt"
"math"
)
func main() {
// 打印默认宽度和精度的圆周率, \n 为换行符
fmt.Printf("%f\n", math.Pi)
// 打印默认宽度, 精度(小数点后的位数)为2的圆周率
fmt.Printf("%.2f\n", math.Pi)
}
复制代码
运行结果如下:
3.141593
3.14
复制代码
2.3 布尔型
在Go
语言中,以关键字bool
来声明布尔类型。布尔类型只有true
和 false
两种值。
if
和 for
语句的条件部分都是布尔类型的值,并且==
和 <
等比较操作也会产生布尔型的值。一元操作符!
对应逻辑非操作,因此!true
的值为false
,一般会采用简洁的布尔表达式,就像用x
来表示x==true
。
布尔值可以和&&(AND)
和||(OR)
操作符结合,并且有短路行为:如果运算符左边值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值。
&&
的优先级比||
高(PS:&&
对应逻辑乘法,||
对应逻辑加法,乘法比加法优先级要高),下面形式的布尔表达式是不需要加小括弧的,如下:
if 'a' <= c && c <= 'z' ||
'A' <= c && c <= 'Z' {
// ...do something...
}
复制代码
注意:Go
语言中布尔类型无法参与数值运算,也无法与其他类型进行转换 !
package main
import "fmt"
func main() {
var a bool
fmt.Print(int(a) * 2) // 将变量 a 强制转换为 int 类型,并乘以 2
}
复制代码
运行上面的代码,会发生编译错误:
cannot convert a (type bool) to type int // 无法将 bool 类型转换为 int 类型
复制代码
2.4 字符串
在Go
语言中,字符串是一个不可改变的字节序列,类型为原生数据类型。准确的来说字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容,也可以说字符串是字节的定长数组。
2.4.1 定义字符串
在Go
语言中,字符串的值通过双引号来包裹的。字符串中可以使用转义字符来实现换行、缩进等效果。如下:
package main
import "fmt"
func main() {
var str = "稀土掘金\n小黑豆豆"
fmt.Println(str)
}
复制代码
运行结果为:
常用的转义字符还包括:
-
\n
:换行符 -
\r
:回车符 -
\t
:tab 键 -
\u
或\U
:Unicode 字符 -
\\
:反斜杠自身
2.4.2 字符串拼接符"+"
两个字符串s1
和s2
可以通过s := s1 + s2
拼接在一起。将s2
追加到s1
尾部并生成一个新的字符串s
。如下:
str := "hello " +
"world!"
复制代码
注意:因为编译器会在行尾自动补全分号,所以拼接字符串用的加号+
必须放在第一行末尾。
也可以使用+=来对字符串进行拼接,如下:
str := "hello" + "world!"
str += "小黑"
fmt.Printf(str)
复制代码
2.4.3 定义多行字符串
如果想实现一个多行字符串时,就必须使用`
反引号,代码如下:
var str = `第一行
第二行
第三行
...
`
fmt.Println(str)
复制代码
2.5 字符
Go
语言中,字符串的每一个元素叫做字符,主要分为以下两种:
-
uint8
类型,或者叫byte
型,代表了ASCII
码的一个字符。 -
rune
类型,代表了一个UTF-8
字符。通常情况下,当需要处理中文、日文、韩文等复合字符时,需要用到rune
类型。
可以在 fmt.Println
中通过 %T
来输出变量的实际类型,代码如下:
package main
import "fmt"
func main() {
var a byte = 'd'
fmt.Printf("%d %T\n", a, a)
var b rune = '豆'
fmt.Printf("%d %T\n", b, b)
}
复制代码
运行代码结果如下:
由上可以得到:
byte
的实际类型是个uint8
,对应的ASCII
编码为100
rune
的实际类型其实是int32
,对应的Unicode
编码为35910
Go
语言中,使用了rune
类型来处理Unicode
编码,这样让基于Unicode
的文本处理更为方便,同时也可以用byte
进行默认的字符串处理,这样对性能和拓展性都有照顾。
三、常量
Go
语言中,常量在代码的编译期就已经确定了,而不是运行时。每种常量的潜在类型都是基础类型:boolean
、string
或数字
。
3.1 定义&声明
Go
语言中定义一个常量非常简单,它和变量的声明方式类似,只需将var
关键字替换成const
即可,代码如下:
const pi = 3.1415926
const url = "juejin.cn"
fmt.Println(pi, url)
复制代码
运行结果如下:
3.2 定义多个常量
常量也是可以同时定义多个的,方式和变量很类似,代码如下:
const (
pi = 3.1415926
url = "juejin.cn"
)
fmt.Println(pi, url)
复制代码
运行结果也和上面一致。
最后,Go
语言的基础语法的第一部分就介绍到这里,对于刚接触Go
语言的我来说,一时半会儿还没有从js
的代码习惯转过来,所以真的不是收藏即学会的。希望大家学完能有所收获!