go结构体函数
这个有点类似于显示对象传递func (a 结构体名) 方法名(参数列表) (返回值列表) {函数体}
如果我们想访问这个结构体成员的内容时,没有this指针这个概念的,需要显式的调用
匿名函数
如果我们要初始化匿名函数,可以使用下面这样的方法
// 这个是带返回值的
f:=func()string{
return "hello world"
}
a:=f()
// 当然我们可以直接调用
func(a int)string{
return "hello world"
}(4)
goto语句
go是支持goto语句的,不过一般不推荐使用
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* 循环 */
LOOP: for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}
go返回值说明
go要求返回参数要么都有变量名要么都没有,必须统一。
import
go的import的最后面一个元素是包名
- import后面跟的是包的路径,而不是包名;
- 同一个目录下可以有多个.go文件,但是只能有一个包;
- 使用第三方库时,先将源码编译成.a文件放到临时目录下,然后去链接这个.a文件,而不是go install安装的那个.a文件;
- 使用标准库时,直接链接.a文件,即使修改了源码,也不会从新编译源码;
- 不管使用的是标准库还是第三方库,源码都是必须存在的,即使使用的是.a文件。
go数据类型
go的关键字
go关键字:
var和const :变量和常量的声明
var varName type 或者 varName : = value
package and import: 导入
func: 用于定义函数和方法
return :用于从函数返回
defer someCode :在函数退出之前执行
go : 用于并行
select 用于选择不同类型的通讯
interface 用于定义接口
struct 用于定义抽象数据类型
break、case、continue、for、fallthrough、else、if、switch、goto、default 流程控制
chan用于channel通讯
type用于声明自定义类型
map用于声明map类型数据
range用于读取slice、map、channel数据
有缓冲的channel和无缓冲的channel比较
无缓冲的channel是同步的,而有缓冲的channel是非同步的
比如c1:=make(chan int) 无缓冲
c2:=make(chan int,1) 有缓冲
c1<-1
无缓冲的 不仅仅是 向 c1 通道放 1 而是 一直要有别的携程 <-c1 接手了 这个参数,那么c1<-1才会继续下去,要不然就一直阻塞着
而 c2<-1 则不会阻塞,因为缓冲大小是1 只有当 放第二个值的时候 第一个还没被人拿走,这时候才会阻塞。
打个比喻
无缓冲的 就是一个送信人去你家门口送信 ,你不在家 他不走,你一定要接下信,他才会走。
无缓冲保证信能到你手上
有缓冲的 就是一个送信人去你家仍到你家的信箱 转身就走 ,除非你的信箱满了 他必须等信箱空下来。
有缓冲的 保证 信能进你家的邮箱
delete函数
delete
关键字用于删除哈希表 map 中的元素, 参数为 map 和其对应的 key
for循环
1.for循环支持continue和break来控制循环,但是它提供了一个更高级的break,可以选择中断哪一个循环
2.go里面没有while和都 while循环,循环全部用的是for循环
go的i++
go语言中的++、–操作符都是后置操作符,必须跟在操作数后面,并且它们没有返回值,所以它们不能用于表达式。
go语言的main函数
- main函数不能带参数
- main函数不能定义返回值
- main函数所在的包必须为main包
- main函数中可以使用flag包来获取和解析命令行参数
nil类型
Go语言中的引用类型只有五个:
切片 映射 函数 方法 通道
nil只能赋值给上面五种通道类型的变量以及指针变量。
go vendor
- 基本思路是将引用的外部包的源代码放在当前工程的vendor目录下面
- 编译go代码会优先从vendor目录先寻找依赖包
- 有了vendor目录后,打包当前的工程代码到其他机器的$GOPATH/src下都可以通过编译
接口
只要两个接口拥有相同的方法列表(次序不同不要紧),那么它们就是等价的,可以相互赋值。 Go语言接口是否可以赋值,是在编译期就确定的。接口的查询是在运行期确定。
A是B的子集,意味着A的方法B中都有,那么A是B的基类,所以A=B是可行的
init函数
- init函数可以在任何包中有0个或1个或多个;
- 首先初始化导入包的变量和常量,然后执行init函数,最后初始化本包的变量和常量,然后是init函数,最最后是main函数;
- main函数只能在main包中有且只有一个,面包中也可以有0或1或多个init函数;
- init函数和main函数都不能被显示调用;
字符串
GO语言中字符串是不可变的,所以不能对字符串中某个字符单独赋值。
map
因为map本身是无序的,for range根据循环对象本身的序列顺序进行遍历,所以 map在 for range 中是无序遍历的,每次遍历的顺序可能都不一样。
go … 操作符
这个一般用于函数拥有多个参数的情况下
下面这种方式调用是没有问题的
add([]int{1, 3, 7}...)
当然这个也可以不用