第一课 Go语言基础语法
特点
-
Go语言特点 a. 高性能,高并发。 b. 语法简单,学习曲线平缓 (如循环只有for循环)(学习快) c. 丰富的标准库 d. 完善的工具链 e. 静态链接 f. 快速编译 (编译速度快) g. 跨平台 (可以开发安卓,ios软件) h. 垃圾回收 (和java一样,无需考虑内存空间释放)
-
Go语言其他优点: 入门简单,开发效率高, 无依赖库版本问题。
-
Go的基本组成: 和C语言相似,go语言的基本组成有:
-
包名用main 否则无法执行,主函数名也是main 否则无法执行
包声明,编写源文件时,必须在非注释的第一行指明这个文件属于哪个包,如package main。
引入包,其实就是告诉Go 编译器这个程序需要使用的包,如import "fmt"其实就是引入了fmt包。
函数,和c语言相同,即是一个可以实现某一个功能的函数体,每一个可执行程序中必须拥有一个main函数。
变量,Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
语句/表达式,在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。
注释,和c语言中的注释方式相同,可以在任何地方使用以 // 开头的单行注释。以 /* 开头,并以 */ 结尾来进行多行注释,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。
(多处借鉴学习blog.csdn.net/weixin_5094…
基础语法
数据类型
数字类型:int ,float,complex(用于实数和虚数)
布尔型:bool
字符串:
派生类型:指针,数组,结构体,Channel类型,函数类型,切片类型,接口类型,Map类型。
数组
声明:
var a[10] int
初始化:
- 声明时进行初始化
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
- 不指定数据长度
在[ ]中填入...
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
- 指定下标进行部分初始化,数组长度已知
balanced := [5]float32(1:2.0, 3:7.0)
注意:
初始化数组中 {} 中的元素个数不能大于 [] 中的数字。 如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小。
数组名意义:
仅仅表示整个数组,是一个完整的值,一个数组变量即是表示整个数组。
字符串
字符串可以通过+拼接,和java一样。
a = "hello" //双引号
字符串操作
字符串格式化:
println:打印多个变量并且换行
printf:用%v打印任意类型的变量,不需要区分
%+v得到更详细的,%#v更详细
结构体
为了定义多个不同的数据类型
首先:声明结构体类型:
定义在main函数外面)
type e struct {
a string
b int
c float
}
声明结构体:
var i e
初始化:
声明时初始化:
x := e{a: "一", b: 1,c: 3.2} //也可以指定一部分
y := e{"一", 3 , 3.2} //也可以
i.h = "sfdsdf" i.g = 3
函数
可以返回多个值。业务逻辑中第一个值是真返回值,第二个是bool或是错误信息之类
定义:
func add(a int, b int ) int {
return a+b;
}
//定义在main函数外
多个返回值时,返回值也可定义两种类型
func add(a int, b int ) (int,double) {
return a+b;
}
接收也是两个变量,如
a,b = add(1,2);
切片
即一种简化版的动态数组
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
声明:
- 指定一个未指定大小的数组来定义切片:
var a []int //不需要说明长度,可以是其他类型
- 使用 make() 函数来创建切片:
var slice1 []string= make([]string, len)
也可以简写为
slice1 := make([]string, len)
初始化:
slice1[0] = 1
slice1[1] = 2
追加元素:
slice1 = append(slice1,3)
slice1 = append(slice1 , 4,5,6) // 追加多个元素, 手写解包方式
slice1 = append(slice1 , []int{1,2,3}...) // 追加一个切片, 切片需要解包
选择数据:
s[2,5] //下标为2到下标为5,不包括下标为5
s[2:] //从下标为2到最后
s[:5] //从第一个(下标0)到下标为5
(注意不是第几个)
转移数据:
copy(c,s)切片s的数据复制到c中
新添加元素:
a = append(a, 0) // 切片扩展1个空间 copy(a[i+1:], a[i:]) // a[i:]向后移动1个位置 a[i] = x // 设置新添加的元素
map
定义:
//使用make函数 map_variable := make(map[KeyType]ValueType, initialCapacity)
键名 值名 可选参数(指 定 Map 的初始容量
//使用字面量创建map
// 使用字面量创建 Map m := map[string]int{ "apple": 1, "banana": 2, "orange": 3, }
或
var l = map[string]int{ "二": 2, "三": 3, }
初始化:
var k = make(map[string]int)
k["orange"] = 5 k["apple"] = 1 k["cherry"] = 4
获取元素:
// 获取键值对 v1 := m["apple"] v2, ok := m["pear"] // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值
修改元素:
// 修改键值对 m["apple"] = 5
获取map长度: len := len(m)
删除元素: delete(m, "banana")
range
快速遍历, for 循环迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。
//m是一个map
for k,v := range m {
fmt.Println(k,v)
}
for k := range m {
//只想读取键
}
指针
一般用来修改参数
声明用*,调用用&
var ip *int / 声明指针变量 /
ip = &a / 指针变量的存储地址 /
JSON处理
保证已有的结构体的变量的首字母都是大写。
即可用json.Marshal()序列化为一个buf数组
buf类似于字符串,但需要用string(buf)来强制类型转换,不然打印出它们的数字编码
变量声明
-
var
获取元素: 1 / const h int = 2
自动推导变量类型/ 定义变量类型
常量 :const h = 1 / const h int = 2
go的常量没有确定的类型,根据上下文自动确定类型
- x := ?
多变量声明:同时声明多个类型相同的变量:
var x, y int var c, d int = 1, 2 g, h := 123, "hello"
全局变量的声明:
var ( a int b bool )
匿名变量
默认值
数值类型: 0 (如数组
布尔类型: false
字符串: ""
条件语句
if-else
if 后的条件没有括号,不然保存时自动去除。
if后面必须接大括号,不能无大括号,if和语句同一行
switch
不同于c++ :case相等后会break,不会跑完所有分支,不用加break。
switch的变量类型可以是任意类型,比如字符串结构体等
写法1:
var x = 12
switch x { case 1: fmt.Println("1") case 2: fmt.Println("2") default: fmt.Println("no")
}
写法2:
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("yes")
default:
fmt.Println("no")
}
循环语句
-
for {
}
-
for i := 1; i < 9; i ++ {
//for后面的3段每一段都可以省略
}
有continue和break关键词
错误处理
error.new("no")
API
时间处理
数字解析
Atoi : 字符串转换为数字
Rtoa/Itoa:与上面相反(没听清)
进程信息
终端命令
运行 go run xxx.go