二、基础语法
2.1、注释
以后写程序要多加注释,这是程序猿的专业和职业道德,不加注释就是耍流氓。
2.1.1、单行注释
//行注释
单行代码注释
2.1.2、多行注释
若果代码量比多,每行加注释。比较麻烦,可以使用多行注释。
除了给代码加上说明,用注释以外,如果你写的代码不想让计算机执行,那么也可以加上注释。
加了注释后代码不会被编译执行,这就是对已有的代码进行注销。
2.2、内存
是一个连续的数据集合,每一个内存存储区域都有唯一的地址标识成为内存地址,内存地址编号是一个无符号十六进制整型数据表示的
2.3、变量
在程序运行过程中,其值能够改变的量称为变量,变量存在内存中
所谓的变量简单的理解就是计算机用来存储数据的。计算机通过变量来保存数据,实际上将数据存储到计算机的内存中。
在这里插入图片描述
可以为内存指定区域起别名,称为变量名。
2.3.1、基本数据类型
GO语言中变量需要先声明后使用且必须使用
1、整型:
整型分为以下两个大类:按长度分为: int8、int16、int32、int64 对应的无符号整型: uint8、uint16、uint32、uint64其中。uint8 就是我们熟知的byte 型,int16对应C语言中的short 型,int64 对应C语言中的Long型。
● 特殊类型:
在使用int和uint 类型时,不能假定它是32位或64位的整型,而是考虑int和uint可能在不同平台上的差异。
● 注意事项:
获取对象的长度的内建len()函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或map的元素数量等都可以用int来表示。在涉及到二进制传输、读写文件的结构描述时。为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int 和uint
2、浮点型:
Go语言支持两种浮点型数:float32 和float64。这两种浮点型数据格式遵循IEEE 754标准: floot32 的浮点数的最大范围约为3.4e38 。可以使用常量定义: math.MaxFLoat32。float64 的浮点数的最大范围约为1.8e308 , 可以使用一个常量定义:math.MaxFLoat64。
GO语言默认小数是float64
3、复数:
复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。
var c1 complex64
c1 = 1 + 2i
var c2 complex128
c2 = 2 + 3i
fmt.Println(c1) //(1+2i)
fmt.Println(c2) //(2+3i)
4、布尔值:
● Go语言中以bool 类型进行声明布尔型数据,布尔型数据只有true (真)和false (假)两个值。
● 布尔类型变量的默认值为false。
● Go语言中不允许将整型强制转换为布尔型。
● 布尔型无法参与数值运算,也无法与其他类型进行转换。
5、字符串:
Go语言中的字符串以原生数据类型出现。使用字符串就像使用其他原生数据类型(int,bool,float32,loat64 等)一样。Go 语言里的字符串的内部文现使用UTF-8 编码。字符串的值为双引号(") 中的内容,可以在Go语言的源码中直接添加非ASCII码字符。
字符串常用操作:
s:="hello 世界"
for _, c := range s { //从字符串中拿出具体的字符
fmt. Printf("%c\t", c) // %c:字符 h e l l o 世 界
}
6、byte和rune类型
● 组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。字符用单引号 (’)包裹起来。
● Go语言的字符有以下两种:
① uint8类型,或者叫byte型,代表了ASCII码的一个字。
② rune类型,代表一个UTF-8字符,rune类型实际是一个int32 。
● 当需要处理中文、日文或者其他复合字符时,则需要用到rune 类型。
● Go使用了特殊的rune类型来处理Unicode。让基于Unicode的文本处理更为方便,也可以使用byte型进行默认字符串处理,性能和扩展性都有照顾。
2.3.2、声明变量
GO语言是静态类型变量,需要声明变量类型
var 变量名 数据类型
批量声明
var (
a int
b string
c bool
)
2.3.3、定义变量
var 变量名 数据类型 = 数据
var a int = 10
func main() {
var PI float64 = 3.14159
var r float64 = 2.5
var s float64
var l float64
//计算面积
s = PI * r * r
//计算周长
l = PI * 2 * r
fmt.Println("面积:", s)
fmt.Println("周长", l)
}
2.3.4、自动类型推导(简短变量声明)
var a = 1//类型推导(根据值判断变量的类型)
fmt.Println(a)
在给变量赋值时,非常麻烦,可以使用自动类型推导,具体示例如下:
num := 5//自动类型推导(简短变量声明)
fmt.Println(num)
自动类型推导,就是不用通过var声明变量,不用指定类型,直接在变量名后面跟 : 号,同时完成赋值。那么GO会根据所赋的值自动推导出变显的类型。如果给num变量赋值为小数,那么该变显的类型为小数类型(浮点)。但是这种凡事 只能在函数中 使用。
通过比较,这种方式比前面的赋值方式要简单方便。这种方式,也是以后开发过程中最常用的方式。
func main() {
PI := 3.14159
r := 2.5
//计算面积
s := PI * r * r
//计算周长
l := PI * 2 * r
fmt.Println("面积:", s)
fmt.Println("周长", l)
}
2.3.5、多重赋值
a,b,c,d := 10,20,30,40
a,b = b,a (数据交换)
2.3.6、匿名变量 _
匿名变量存完之后直接丢弃,不能对 _ 进行变量的操作。不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。(在Lua 等编程语言里,匿名变量也被叫做哑元变量)
2.3.7、注意
● 在go语言中不同的数据类型不能进行计算可以通过类型转换。
● 函数外的每个语句都必须以关键字开始( var,const,func等)
● := 不能使用在函数外。
● _ 多用于占位,表示忽略值。
● 同一个作用域不能多次声明同一个变量。
2.3.8、总结
变量定义格式:
var 变量名 数据类型 声明
var 变量名 数据类型 = 数据 值定义
var 变量名 = 数据 类型推导
变量名 :=值 自动类型推导
2.3.9、命名规范
① 名字必须以 一个字母(Unicode 字母) 或 下划线 开头。后面可以跟任意数量的 字母、数字或下划线。
② 大写字母和小写宇母是不同的: heapSort和Heapsort是两个不同的名字。
③ 除了上面提到的规范要求以外,GO语言自己特有的,具有一定含义的一些字符,也不能作为变量名称。例如,func, fmt,print等等,这些都是GO自带的,具有特殊含义的字符,称为关键字(25个)。
保留字(37)
④ 起一个有意义的名字,尽量做到看一眼就知道是什么意思(提高代码可读性)比如:名字就定义为name。定义学生用student
⑤ 小驼峰式命名法(lower camel case):第一个单词以小写宇母开始;第二个单诃的首宇母大写,例如: myName、aDog 。
⑥ 大驼峰式命名法(upper camel case) :每一个单字的首宇母都采用大写宇母,例如: FirstName、 LastName 。
⑦ 还有一种命名法比较流行,就是用下划线 _ 来连接所有的单词,比如send_buf。
Go推荐用驼峰式命名
2.4、格式输出
fmt.Println()//自带换行
fmt.Print()//不带换行
fmt.Printf("占位符%f", 浮点型变量)
%f:此占位符默认保留六位小数。
%3d:此占位符 不足三位整数,补齐三位(用空格),超过则不作处理。
%.3f:此占位符保留3位小数,第四位四舍五入。
%t:此占位符是boolen类型的。
%s:此占位符是string 类型的。
%c:此占位符是byte(字节类型)类型的。
%p:此占位符是内存地址。
%b:把十进制转换成二进制
%o:把十进制转换成八进制
%x:把十进制转换成十六进制
%v:字符串,与%s的输出格式相同
%#v:字符串,会将字符串用“”包裹
2.5、接收输入
& :取地址运算符
fmt.Scanf("%d", &l)
fmt.Scanf("%3d",&a)//只接受前三位
fmt.Scan(&l)
## **2.6、常量**
● 常量的存储位置在数据区。
● 栈区系统为每一个应用程序分配1M空间用来存储变量,在程序运行结束系统会自动释放。
● 常量的存储位置在数据区不能通过&取地址来访问。
● 常量一般用大写字母表示。
● 常量定义后,在运行期间是不能修改的。
2.6.1、定义
const A int = 10
const A1 = 10
const (
B int = 10
C bool = false
D = 20
)
const (
F = 10
G //默认等于上一个常量10
H
)
2.6.2、字面常量
以下的常量称为字面常量
fmt.Println(123)
fmt.Println("hello world")
所谓字面常量(literal), 是指程序中硬编码的常量,
3.1415 //浮点类型的常量
3.2 + 12i //复数类型的常量
true //布尔类型的常量
"foo" //字符申常量
2.7、iota(常量计数器,类枚举)
常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不用每行都写一遍初始化表达式。
注意:在一个const声明语句中,在第一个声明的常量所在的行,iota 将会被置为0(不管iota在什么位置),然后在每新增常量声明的行(不管有没有iota)加一。
2.7.1、举例
func main() {
const (
a = iota //0
b = iota //1
c = iota //2
d = iota //3
)
}
或者(iota只在第一行):
func main() {
const (
a = iota //0
b //1
c //2
d //3
)
}
Iota不在第一行:
func main() {
const (
a = 100 //100
b = iota //1
c //2
d //3
)
}
Iota不是所有行都存在:
func main() {
const (
a = iota //0
b = 100 // 100
c = iota //2
d //3
)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
如果定义常量是枚举写在同一行值相同,换一行值不同:
func main() {
const (
a = iota //0
b, c = iota, iota //1
d, e //2
)
}
在定义常量iota时可以为其赋初始值但是换行后不会根据值增涨:
func main() {
const (
a = 10 //10
b, c = iota, iota //1
d, e //2
)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
}
func main() {
const (
a = iota //0
b, c = iota, 100 //1 100
d, e //2 100
)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
}
2.7.2、小练习(定义数量级)
func main() {
const (
_ = iota
KB = 1 << (10 * iota)
MB = 1 << (10 * iota)
GB = 1 << (10 * iota)
TB = 1 << (10 * iota)
PB = 1 << (10 * iota)
)
fmt.Println(KB) //1024
fmt.Println(MB) //1048576
fmt.Println(GB) //1073741824
fmt.Println(TB) //1099511627776
fmt.Println(PB) //1125899906842624
}
2.8、运算符:
2.8.1、算术运算符
注意:
① 整型除法,除数不能为0。浮点型除法,除数可以为0.0,结果是+int(正无穷)。
② 取余时,只能取大于0的数。
③ 自增自减只能单独使用,不能用在表达式中。
④ 不同类型不能进行运算(int32与int64,int与float),运算需要进行类型转换(一般习惯于将低类型转化为高类型,如将int32转为int64,防止数据溢出)。
2.8.2、类型转换
数据类型(变量/表达式)
func main() {
a := 10
b := 3.14
c := float64(a) * b 将不同类型转成相同共型进行计算操作
fmt.Println(c) //31.400000000000002
}
2.8.3、赋值运算符
2.8.4、关系运算符
2.8.5、逻辑运算符
2.8.6、位运算符
位运算符对整数在内存中的二进制位进行操作。
// 101 5
// 010 2
// &: 按位与(两位均为1结果1)
fmt.Println(5 & 2)// 000 0
// |: 按位或(两位有1个为1结果1)
fmt.Println(5 | 2) // 111 7
// ^: 按位异或(两位不一样结果为1)
fmt.Println(5 ^ 2) // 111 7
//将二进制位左移
fmt.Println(1<<2)// 4 将 00000001 变为00000100
//将二进制位右移
fmt.Println(8>>2)// 2 将 00001000 变为00000010
2.8.7、其他运算符
2.8.8、运算符优先级
括号、数组下标,结构体成员>单目运算符(!& *)>双目运算符 >乘除>加减>关系>逻辑>赋值