本次声明与已声明的 v 处于同一作用域中(若 v 已在外层作用域中声明过,则此次声明会创建一个新的变量§),
在初始化中与其类型相应的值才能赋予 v,且在此次声明中至少另有一个变量是新声明的。
append
方法,如果增加元素的是另外的切片,则需要使用append(mySlice,mySlice2...)
三点copy()
方法,用于将内容从一个切片复制到另外的一个切片==
,可以自定义一个精度,再用两者的差的绝对值去和精度比较,如果小于精度值,则认为两者相等,和C语言类似。import "math"
/**
判断两值是否相等
**/
func IsEqual(f1,f2,p float64) bool{
return math.Abs(f1-f2) < p
}
return
语句放在 包含if...else分支中,否则会编译失败default
关键字的。
如果不设定swich后面的表达式,则相当于if...else...的作用;如果一个case紧跟下一个case,则需要在当前case中加上fallthrough
关键字a := []int{1, 2, 3, 4, 5,6,7}
JLOOP:
for i,j := 0,len(a)-1;i < j; i, j = i + 1, j-1 {
a[i], a[j] = a[j], a[i]
break JLOOP
}
func Add(a,b int) (ret int,err error){
if a < 0 || b < 0 {
err = errors.New("Should be non-negative number")
}
return a+b, nil
}
...type
,再用for...range...进行迭代获取.如果希望传入任意类型的可以指定类型为interface{}
,如:func printf(fomrt string, args ...interface{}){
}
switch arg.(type)
来进行变量的类型判断panic()
方法,接收任意的数据类型,调用时正常的函数执行流程将立即终止。recover()
函数用于终止错误流程处理,一般情况下,recover()应该在一个使用了defer
关键字的函数中执行以有效截取错误处理流程。defer func(){
if r := recover(); r != nil{
log.Printf("Runtime error caught:%v",r)
}
结构体:定义的一组字段的集合 结构体初始化,new(Student) == &Student{}是等价的。 接口:定义的一组方法的集合
func (a *Integer ) Add (b Integer) {
retrun *a + b
}
go 结构体中的字段还有一个 在变量类型后还有一个tag
,作为可选项,要获取tag内容,需要利用反射包来实现的。
defer
语句,因此,可以用来做资源清理(比如数据库连接释放,锁释放)。
2.多个defer
语句,按先进后出的方式执行。
3.defer
语句中的变量,在defer 声明时就决定了。内置函数 new:用来分配内存,主要用来分配值类型,比如int,struct,返回的是指针。 make:用来分配内存,主要用来分配引用类型,比如chan,map,slice,出现这种用差异的原因在于,这三种类型本质上为引用数据类型,它们在使用前必须初始化。 panic和recovery用来处理错误。
...
有两个作用,一是作可变参数,另外可以把一个把一个slice展开
递归的设计原则: 1.一个大的问题能分解成相似的小的问题 2.定义好出口条件
闭包:一个函数和与其相关的引用环境组合而成的实体。 函数的返回值是一个函数
sort 包可以进行排序,使用sort.SearchInts()方法时需要传的参,slice必须是有序的
var mapkeTyPE 也可以用make初始化
a["hello"] = "world" //插入和更新 val,ok := a["hello"] //查找 delete(a,"hello") //删除 for k,v := range a{
fmt.Println(k,v)
}
锁机制: 1.互斥锁 Mutex
struct的内存布局,struct中所有字段在内存是连续的
*双链表定义:如果有两个指针分别这指向前一个节点和后一个节点,我们就叫双链表
链表:尾部插入法,头部插入法 type Student struct{ Name string Next *Student }
二叉树:如果每个节点有两个指针分别用来指向左子树和右子树,我们把这样的结构叫做二叉树 type Student struct{ Name string left *Studnent right *Student }
遍历时有深度优先和广度优先的方法 深度优先,可以用递归
广度优先,可以用队列
在结构体中,结构体中的匿名字段可以实现其他语言中的所谓“继承”的效果,即一个结构体嵌套了另外一个匿名结构体。
var t int
var x interface{}
x = t
y = x.(int) //转成int
或 y ,ok = x.(int) //转成int,带检查
判断一个变量是否实现了某个接口,可以用
var v MyStruct
var f interface{}
f = v
if sv,ok := f.(Stringer){
}
还有这个:
swithc x.(type){
}
Import("reflect")
相关函数:
a. reflect.TypeOf,获取变量的类型返回reflect.Type类型
b. reflect.ValueOf ,获取变量的值,返回reflect.Value类型
c. reflect.Value.Kind 获取变量的类别(如返回struct
),返回一个常量,注意类别和类型的区别
d. reflect.Value.Interface,转换interface{}类型
用反射操作结构体: a. relect.Value.NumField() 获取结构体中字段的个数 b. relect.Value.Method(n).Call来调用结构体中的方法
终端读写: 操作终端相关的句柄常量:
Errorf和error.New
并发和并行的区别:
协程和线程:
channel: