变量和常量
首先我们需要知道变量跟常量的区别:变量是一个可变的值,而常量是一个恒定不变的值。
变量
变量的功能是存储数据,不同的变量保存的数据类型也不一样。我们常见的变量类型有整形(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 语言入门指南:基础语法和常用特性解析 (中) 》。
码字不易,如果您看到了这里,听我说谢谢您。
如果您觉得本文还不错,还请留下您小小的赞。
如果您看了本文有所感受,还请留下您宝贵的评论。