Go语言学习
后期的后端主要围绕go语言展开,这几天花了点时间看了一下go语言相关的知识,并进行了一定的代码书写。 如果有C和Python的基础就会发现go的知识点是相当简单的,大部分都是和C都一样的。我在这里做一点简单的总结就行了。
基础语法
- package:定义包名;
- import:表示导入包名;
- func:表示函数名称,(通常为程序第一个执行函数,如果没有Init());
- 注释:和C一样
- 大写字母开头的标识符可被外部包使用,小写仅内部使用;
- 起始大括号不能单独成行
示例:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
支持数据类型:
- 布尔
- 数字
- 字符串
- 其他:指针、数组、结构化、Channel、函数、切片、接口、Map
go 语言变量
两种变量声明模式,均可进行初始化或者不进行初始化。
var id type
var id1, id2 type
go 常量
const
来定义
iota
用法注意一下
运算符
算术、关系、逻辑、位、赋值、其他等
条件语句
没有 三目运算符,其他都类似。
循环
循环语句: for
循环控制: break、continue、goto
函数
格式
func function_name( [parameter list] ) [return_types] {
函数体
}
可以多值返回
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("Google", "Wang")
fmt.Println(a, b)
}
结果:
Wang Google
注意:值传递和引用传递的区别
- 值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
- 引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
函数:
- 函数作为另一个函数的实参
- 闭包:匿名函数
- 方法:c.he()
变量作用域
- 函数内定义的:局部变量
- 函数外定义的:全局变量
- 函数定义中的:形式参数,作为局部变量使用。
Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑
nil
为pointer的默认初始化值
数组
定义方式
var variable_name [SIZE] variable_type
示例
var balance [10] float32
var 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[4] = 50.0
类似C
go指针
取地址符:&
指针定义
var var_name *var_type
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
指针使用流程:
- 定义指针变量 (var ip *int)
- 为指针变量赋值 (ip=&a)
- 访问指针变量指向地址的值 (*ip)
空指针:nil
区分几个概念:
- 指针数组:数组中都存在的是变量地址的指针
var ptr [MAX]*int
- 数组指针:指向数组的指针,一般为单一指针,指向数组中的某一个元素
- 指向指针的指针
var ptr **int;
a = 3000
/* 指针 ptr 地址 */
ptr = &a
/* 指向指针 ptr 地址 */
pptr = &ptr
- 如何向函数传递指针参数
swap(&a, &b);
func swap(x *int, y *int){
}
结构体
将不同类型的变量放在同一集合中访问。
type struct_variable_type struct {
member definition
member definition
...
member definition
}
variable_name := structure_variable_type {value1, value2...valuen}
//或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
结构体指针:
var struct_pointer *Books
切片
类似python。
相关函数:make()、append()、copy()、len()、cap()
Range
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对(返回的是key)。
Map
类似python中的字典,略有不同。
Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
定义:
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)
递归函数
我调我自己, 容易内存爆炸!
package main
import "fmt"
func Factorial(n uint64)(result uint64) {
if (n > 0) {
result = n * Factorial(n-1)
return result
}
return 1
}
func main() {
var i int = 15
fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i)))
}
接口实现(interface)
它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
/* 定义结构体 */
type struct_name struct {
/* variables */
}
/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/* 方法实现*/
}
例子
package main
import (
"fmt"
)
type Phone interface {
call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}
func main() {
var phone Phone
phone = new(NokiaPhone)
phone.call()
phone = new(IPhone)
phone.call()
}
错误类型处理
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
type error interface {
Error() string
}
go支持并发
通过go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。
语法:
//go 函数名( 参数列表 )
go f(x, y, z)
channel:通道(channel)是用来传递数据的一个数据结构
通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
示例:
ch <- v // 把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据
// 并把值赋给
//创建通道
ch := make(chan int)
总结
学习编程语言,知道基本语法,后边相关函数调用使用时候边用变查询!