@TOC
第一个Go程序-hello,world!
国际惯例,编写第一个程序,首先打印“hello,world!”。
1 | package main |
程序基本结构:
1 | package //包声明 |
OK,一行一行来。
- package关键字定义一个叫main 的包,main包是个特殊的包,程序的入口就在这个包。
- import关键字用来导入程序中使用到的外部包。
- func 是用来声明函数的,main函数是程序的入口函数。
- fmt是go内置的一个包,fmt.println()函数打印输出并在末尾自动换行。
变量和常量
标识符和关键字
标识符
- 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_(下划线)组成,并且只能以字母和_开头。举个栗子,_a123, abc, a_4等等。
关键字
- 关键字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。
- Go语言中有25个关键字:
1 | break default func interface select |
- 此外,Go语言中还有37个保留字。
1 | Constants: true false iota nil |
变量的来历
程序运行过程中的数据都是保存在内存中,我们想要在代码中操作某个数据时就需要去内存上找到这个变量,但是如果我们直接在代码中通过内存地址去操作变量的话,代码的可读性会非常差而且还容易出错,所以我们就利用变量将这个数据的内存地址保存起来,以后直接通过这个变量就能找到内存上对应的数据了。
变量(Variable)的功能是存储数据。不同的变量保存的数据类型可能会不一样。经过半个多世纪的发展,编程语言已经基本形成了一套固定的类型,常见变量的数据类型有:整型、浮点型、布尔型等。
Go语言中的每一个变量都有自己的类型,并且变量必须经过声明才能开始使用。
声明变量
- 变量的标准声明方式:
1 | var 变量名 变量类型 |
- 变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号。
1 | var age int |
批量声明
每次声明变量都要写var关键字十分繁琐,Go还支持变量的批量声明:
1 | var ( |
初始化变量
Go语言在声明变量时,自动对变量对应的内存区域进行初始化操作。每个变量会初始化其类型的默认值,例如:
- 整型和浮点型变量的默认值为0。
- 字符串变量的默认值为空字符串。
- 布尔型变量默认值为false。
- 切片、函数、指针变量的默认值为nil。
当然,我们依然可以在变量声明时赋予变量一个初始值。
- 标准格式
1 | var 变量名 变量类型 = 表达式 |
栗子:
1 | var hp int = 100 |
- 编译器推导类型
在标准格式的基础上,将int省略后,编译器会尝试根据等号右边的表达式推导hp变量的类型。
1 | var hp = 100 |
举一堆栗子:
1
2
3
4
5var attack = 40
var defence = 20
var damageRate float32 = 0.17
var damage = float32(attack -defence) * damageRate
fmt.Println(damage)
- 短变量声明及初始化
一种更为简洁的写法,在开发中使用比较普遍。
1 | hp := 10 |
如果hp已经被声明过,但依然使用“:=”时编译器会报错。
1 | //声明hp变量 |
编译报错如下:
1 | no new variables on left side of := |
匿名变量
在使用多重复值时,若果不需要再左值中接收变量,可以使用匿名变量。
匿名变量用_(下划线)表示,使用时,只要在变量声明的地方使用下划线代替即可。
1 | func GetData()(int, int){ |
常量和iota
相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。
1 | const pi = 3.1415 |
声明了pi和e这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。
多个常量也可以一起声明:
1 | const ( |
const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:
1 | const ( |
上面示例中,常量n1、n2、n3的值都是100。
iota
iota是go语言的常量计数器,只能在常量的表达式中使用。
iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。
举个例子:
1 | const ( |
几个常见的iota示例:
使用_跳过某些值
1 | const ( |
iota声明中间插队
1 | const ( |
定义数量级 (这里的<<表示左移操作,1<<10表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2<<2表示将2的二进制表示向左移2位,也就是由10变成了1000,也就是十进制的8。)
1 | const ( |
多个iota定义在一行
1 | const ( |
数据类型
整型
整型分为以下两个大类: 按长度分为:int8、int16、int32、int64 对应的无符号整型:uint8、uint16、uint32、uint64
其中,uint8就是我们熟知的byte型,int16对应C语言中的short型,int64对应C语言中的long型。
类型 | 描述 |
---|---|
uint8 | 无符号 8位整型 (0 到 255) |
uint16 | 无符号 16位整型 (0 到 65535) |
uint32 | 无符号 32位整型 (0 到 4294967295) |
uint64 | 无符号 64位整型 (0 到 18446744073709551615) |
int8 | 有符号 8位整型 (-128 到 127) |
int16 | 有符号 16位整型 (-32768 到 32767) |
int32 | 有符号 32位整型 (-2147483648 到 2147483647) |
int64 | 有符号 64位整型 (-9223372036854775808 到 9223372036854775807) |
特殊整型
类型 | 描述 |
---|---|
uint | 32位操作系统上就是uint32,64位操作系统上就是uint64 |
int | 32位操作系统上就是int32,64位操作系统上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
浮点型
Go语言支持两种浮点型数:float32和float64。这两种浮点型数据格式遵循IEEE 754标准: float32 的浮点数的最大范围约为 3.4e38,可以使用常量定义:math.MaxFloat32。 float64 的浮点数的最大范围约为 1.8e308,可以使用一个常量定义:math.MaxFloat64。
复数
complex64和complex128。
复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。
1 | var c64 complex64 |
布尔型
Go语言中使用bool来声明布尔类型变量,布尔类型的值只有true和false两个值。
字符串
Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64 等)一样。 Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为双引号(“)中的内容,可以在Go语言的源码中直接添加非ASCII码字符。
字符串转义符
转义符 | 含义 |
---|---|
\r | 回车符(返回行首) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
\’ | 单引号 |
\” | 双引号 |
\\ | 反斜杠 |
字符串操作
方法 | 介绍 |
---|---|
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
字符串修改以及类型转换
修改字符串
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
1 | func changeString() { |
类型转换
Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。
强制类型转换的基本语法如下:
1 | T(表达式) |
其中,T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等.
比如计算直角三角形的斜边长时使用math包的Sqrt()函数,该函数接收的是float64类型的参数,而变量a和b都是int类型的,这个时候就需要将a和b强制类型转换为float64类型。
1 | func sqrtDemo() { |
运算符
算术运算符
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
注意: ++(自增)和–(自减)在Go语言中是单独的语句,并不是运算符。 |
关系运算符
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 |
逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。 |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。 |
! | 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。 |
位运算符
运算符 | 描述 |
---|---|
& | 参与运算的两数各对应的二进位相与。(两位均为1才为1) |
| | 参与运算的两数各对应的二进位相或。(两位有一个为1就为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1(两位不一样则为1) |
<< | 左移n位就是乘以2的n次方。“a << b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
>> | 右移n位就是除以2的n次方。“a>>b”是把a的各二进位全部右移b位。 |
赋值运算符
运算符 | 描述 |
---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
<<= | 左移后赋值 |
>>= | 右移后赋值 |
&= | 按位与后赋值 |
|= | 按位或后赋值 |
^= | 按位异或后赋值 |