变量和常量
首先我们需要知道变量跟常量的区别:变量是一个可变的值,而常量是一个恒定不变的值。
变量
变量的功能是存储数据,不同的变量保存的数据类型也不一样。我们常见的变量类型有整形(int)、浮点型(float)、布尔型(bool)等。
变量声明
Go语言中变量声明格式为:
go
var 变量名 变量类型
声明变量需要以var开头,同时声明变量不需要分号结尾。举例:
go
var name string
var age int8
var flag bool
go语言中支持批量声明变量
go
var (
name string
age int8
flag bool
)
变量初始化
go语言在声明变量时,会自动为变量对应的内存区域进行初始化,并且每个变量会被初始化为默认值。例如:整形和浮点型的默认值都是0;字符串默认值是空字符串;布尔值默认值是false;切片、函数、指针变量的默认值都是nil。 变量初始化格式:
go
var 变量名 类型 = 值
变量初始化也可以一次初始化多个变量
go
var name string = "zhangsan"
var age int8 = 18
var city,province string = "江苏", "苏州"
类型推导
我个人非常喜欢go语言中的这个类型推导,我们可以让编译器自动根据右值来推导出变量的类型,依此来完成初始化,甚至是在基于函数返回值的时候。当我们不确定具体需要什么类型时,我们也可以使用类型推导来完成变量初始化。
go
var name = "zhangsan"
var age = 18
短变量声明
在函数内部使用类型推导时,我们可以将var省略,直接使用:=的方式来初始化变量,但是只能在函数内部使用,无法在函数外部使用。
go
package main
import ("fmt")
func add(x, y int8) int8 {
return x + y
}
//全局变量
var a := 100
func main() {
//局部变量
n := 10
m := 20
res := add(n, m)
fmt.Println(res) //30
}
匿名函数
当一个函数有多个返回值时,而我们只需要其中一个值时,我们可以使用匿名函数。匿名函数使用一个下划线_来表示。_表示占位符,不会占用空间以及内存。
go
package main
import ("fmt")
func two() (string, string){
return "XXX", "YYY"
}
func main() {
x, _ := two()
_, y := two()
fmt.Println("x=", x) //x=XXX
fmt.Println("y=", y) //y=YYY
}
常量
常量声明
常量一般用于声明那些不会变的值,同时常量的使用与变量的使用几乎一致,只是将var换成了const,但是常量在声明时就必须赋值。
go
const pi = 3.1415926
const (
a = 100
b = 200
)
//const在同时声明多个变量时,可以省略下面的值,如果省略了那么下面的值和其上面一行的值相同
const (
a1 = 11
a2
a3
)
//此时a2,a3的值都是11,与a1相同
iota
iota是一个常量计数器,只能在常量中使用。 iota在const出现时就会重置为0,而const每额外声明一个常量,iota的值就会+1。
go
const (
a1 = iota //0
a2 //1
a3 //2
)
//我们也可以使用_来跳过中间值
const (
b1 = iota //0
b2 //1
_
b3 //3
)
//iota也可以用于中间插队
const (
c1 = iota //0
c2 = 222 //222
c3 = iota //2
c4 //3
)
基本数据类型
整型
go语言中的整型分为两类,一类是有符号的整型int,还有一类是无符号的整型uint。
这里我们需要注意,在go语言中,我们在使用整型时,需要指定其大小,这也是go语言中一点非常讨厌。当我们在初始化一个变量时,我们需要考虑其在之后可能会占用的内存大小,如果考虑不当就会产生很多问题在Java中我们就不需要考虑这一点。如果我们不给其指定大小,那么int和uint的大小就会按照操作系统的大小而定。32位的操作系统就会使其成为int32,uint32;64位的操作系统就会使其成为int64,uint64。
这里我们需要注意,uint8类型就是我们常见的byte类型。而int32类型就是rune类型,rune类型代表一个UTF-8字符。
| 类型 | 描述 |
|---|---|
| int | 根据操作系统大小而定 |
| int8 | 有符号的8位整型 |
| int16 | 有符号的16位整型 |
| int32 | 有符号的32位整型 |
| int64 | 有符号的64位整型 |
| uint | 根据操作系统大小而定 |
| uint8 | 无符号的8位整型 |
| uint16 | 无符号的16位整型 |
| uint32 | 无符号的32位整型 |
| uint64 | 无符号的64位整型 |
浮点型
go语言中只有两种浮点型:float32和float64。float32就相当于Java中的float,而float64就相当于Java中的double,我们在声明浮点型时也需要考虑其可能使用的大小,否则会造成内存浪费。
复数
go语言中有两种复数,complex64和complex128。复数有实部也有虚部,而实部和虚部的大小是一致的,例如complex64的实部和虚部大小都是32位,而complex128的实部和虚部大小都是64位。
go
var a1 complex64
a1 = 1 + 2i
var a2 complex128
a2 = 3 + 4i
fmt.Println(a1) //(1+2i)
fmt.Println(a2) //(3+4i)
布尔值
go语言中的布尔值是bool类型,而布尔值数据也只有true和false两个值。布尔类型的默认值是false。
go
var flag bool
fmt.Println(flag) //false
字符串
go语言中的字符串的内部实现使用UTF-8编码,而字符串的值用""声明。
go
s1 := "hello"
s2 := "go"
fmt.Println(s1, s2) //hello go
字符串转义符
如果想要在字符串中使用一些符号或者操作,需要使用其转义符。这些转义符在大部分语言中都是相同的,我这里就不多做说明了,讲三个常用的转义符:
| 转义符 | 含义 |
|---|---|
| \r | 回车符 |
| \n | 换行符 |
| \t | 制表符 |
多行字符串
在go语言中,我们想要定义一个多行字符串时,需要使用反引号声明。
go
s1 := `aaa
bbb
ccc
`
fmt.Println(s1)
//输出结果
//aaa
//bbb
//ccc
字符串的常用操作
go语言中有一些字符串的常用操作,这使得我们在字符串的使用上非常便捷。
| 方法 | 介绍 |
|---|---|
| len(str) | 求长度 |
| + 或 fmt.Sprintf | 拼接字符串 |
| strings.Split | 分割 |
| strings.contains | 判断是否包含 |
| strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
| strings.Index(),strings.LastIndex() | 子串出现的位置 |
| strings.Join(a[]string, sep string) | join操作 |
类型转换
go语言中有强制类型转换,没有隐式类型转换。但是我们需要注意,这里的强制类型转换,不是让我们将布尔值转换成整型值,这是不合理的,我们需要在其合理的范围内进行转换。
go
T(表达式)
这里的T表示要转换的类型;而表达式表示需要转换的值,包括变量、函数返回值等。
go
a1 := 3.33
a2 := 4.44
a3 := int8(a1+a2)
fmt.Println(a3) //7
运算符
go语言中内置的运算符有:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
算数运算符
| 运算符 | 描述 |
|---|---|
| + | 相加 |
| - | 相减 |
| * | 相乘 |
| / | 相除 |
| % | 求余 |
注意:++表示自增,--表示自减。这是单独的语句,在go语言中不是运算符。 |
关系运算符
| 运算符 | 描述 |
|---|---|
| == | 2==3 false |
| != | 2!=3 true |
| > | 2>3 false |
| >= | 2>=3 false |
| < | 2<3 true |
| <= | 2<=3 true |
逻辑运算符
| 运算符 | 描述 |
|---|---|
| && | 逻辑AND运算符。两边都为true,结果则为true |
| || | 逻辑OR运算符。两边有一个为true,结果就是true |
| ! | 逻辑NOT运算符。条件为true,则为false |
位运算符
位运算符用于对整数在内存中的二进制进行操作。
| 运算符 | 描述 |
|---|---|
| & | 参与运算的两数各对应的二进制相与(两位均为1才为1) |
| | | 参与运算的两数各对应的二进制相或(两位有一个为1就为1) |
| ^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(两位不一样则为1) |
| << | 左移n位就是乘以2的n次方。 "a<<b"是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
| >> | 右移n位就是除以2的n次方。 "a>>b"是把a的各二进位全部右移b位。 |
赋值运算符
| 运算符 | 描述 |
|---|---|
| = | x = y |
| += | x+=y x=x+y |
| -= | x-=y x=x-y |
| *= | x*=y x=x*y |
| /= | x/=y x=x/y |
| %= | x%=y x=x%y |
| <<= | x<<=y x=x<<y |
| >>= | x>>=y x=x>>y |
| &= | x&=y x=x&y |
| |= | x|=y x=x|y |
| ^= | x^=y x=x^y |
流程控制
每种语言中都需要控制整体逻辑的走向以及各部分的先后排序,而我们正是通过流程控制符来完成这一需求。
在go语言中,for是万能的。以Java举例,go语言中的for不仅拥有Java语言中的for功能,还拥有Java语言中的while功能。go语言中常用的流程控制符有for和if,go语言中还有switch和goto两种流程控制符,但是使用不多,主要是为了简化代码,降低重复代码而使用的。
if else(分支结构)
go语言中if条件判断的格式如下:
go
if 表达式1 {
分支1
} else if 表达式2 {
分支2
} else {
分支3
}
当表达式1的结果为true时,就会执行分支1,反之则会判断表达式2,如果都不满足,则会执行分支3的代码。
go语言的if条件判断省略掉了表达式两边的括号,使得代码十分简洁。但是go语言中有个规定,那就是{必须与if/else if 表达式/else在同一行,否则会编译失败。
go
func ifDemo() {
score := 90
if score > 90 {
fmt.Println("A")
}else if score >= 80 {
fmt.Println("B")
}else if score >= 70 {
fmt.Println("C")
}else if score >= 60 {
fmt.Println("D")
}else{
fmt.Println("E")
}
}
for(循环结构)
go语言中所有的循环结构都用for来实现。
for循环的基本格式:
go
for 初始语句;条件表达式;结束语句{
循环体语句
}
条件表达式返回true时就会一直执行,直到返回false停止。
go
for forDemo() {
for i:=0;i<3;i++ {
fmt.Println(i)
}
//for循环的初始语句和结束语句也可以被省略掉
i := 0
for ;i<3;i++ {
fmt.Println(i)
}
for i<3 {
fmt.Println(i)
i++
}
}
go语言中的for还充当着其他语言中while的作用。
go
func forDemo() {
for {
//无限循环体
}
}
go语言中的for还有另外一种用法,for range,一般用于遍历数组、切片、字符串、map和通道。使用for range一般用于获取索引和值,键和值以及通道内的值。
go
func forDemo() {
m := []int{1,2,3}
for i, v := range m {
fmt.Println(i, v)
//i表示索引,v表示值
}
}
switch case(条件判断)
go语言中switch用法与其他语言类似,然而go语言中的case可以有多个值,但是只能有一个default。go语言的case还可以使用一个表达式来代替,这使得switch的效率大大提升。
go
func switchDemo() {
s := 2
switch s {
case 1:
fmt.Println("a")
case 2:
fmt.Println("b")
case 3:
fmt.Println("c")
}
switch n:=3; n {
case 1,3,5,7,9:
fmt.Println("奇数")
case 2,4,6,8:
fmt.Println("偶数")
}
switch score:=80; score {
case score>=60:
fmt.Println("合格")
case score<60:
fmt.Println("不合格")
}
}
go语言中还有一个fallthrough语法,可以执行满足条件的case的后面一个case。
go
func switchDemo() {
s := "a"
switch {
case s=="A":
fmt.Prinltn("A")
fallthrough
case s=="B":
fmt.Println("B")
case s=="C":
fmt.Println("C")
}
//输出结果:
//A
//B
}
goto(跳转到指定标签)
goto在go语言中用于代码跳转,使用goto可以快速跳转到其他代码,常用于快速结束循环、避免重复退出。
go
func gotoDemo() {
flag := true
i := 0
for flag {
fmt.Println(i)
i++
if i==3 {
goto flagTag
}
}
flagTag :
flag = false
}
break和continue
break和continue在go语言中的语法与其他语言几乎一致。break一般用于结束循环的使用,常用于一段代码中找到结果时直接进行break结束即可。continue一般用于结束当前循环使用,常用于当前结果不符合我们预期的结果时,我们可以使用continue来跳过当前循环,进行下一轮循环。
go
func break_continue() {
for i:=0;;i++ {
if i==3 {
fmt.Println(i)
break
}
}
//输出结果:
//3
for i:=0;i<5;i++ {
if i%2==0 {
continue
}
fmt.Println(i)
}
//输出结果:
//1
//3
}
小结
到目前为止,我们认识了go语言中的基础语法使用,包括变量、常量声明、基本数据类型、运算符的使用以及流程控制符。希望小伙伴们能够有所收获。当然,go的基础语法还远不止这些,敬请收看下篇《Go 语言入门指南:基础语法和常用特性解析 (中) 》。
码字不易,如果您看到了这里,听我说谢谢您。
如果您觉得本文还不错,还请留下您小小的赞。
如果您看了本文有所感受,还请留下您宝贵的评论。