函数大写表示公有,小写表示私有
        首先闭包的特点是当闭包函数引用外部变量的时候,会把这个变量放在堆中,所以在内部函数引用外部函数的变量时,值不会被释放  
        
package main
import "fmt"
func externalFunc(count int) func() int{
    return func() int {
        count++
        return count
    }
}
func main()  {
    // 这时候的external是个函数,externalFunc函数返回了个匿名函数
    external := externalFunc(1)  // 这时候的count == 1
    fmt.Println(external()) //输出2
    fmt.Println(external()) //输出3
    fmt.Println(external()) //输出4
}
用法1.函数计数器
// 函数计数器
func counter(f func()) func() int {  
	n := 0
	return func() int {
		f()
		n += 1
		return n
	}
}
// 测试的调用函数
func foo() {
	fmt.Println("call foo")
}
func main() {
	cnt := counter(foo)
	cnt()
	cnt()
	cnt()
	fmt.Println(cnt())
}
/*
输出结果:
call foo
call foo
call foo
call foo
4
*/
2)装饰器和中间件,即函数作为参数传递
func wrapping(f func() string) {
	fmt.Println("do my work...")
	fmt.Println("wrapping function: ", f())
	fmt.Println("my work finished !")
}
func sayHello() string {
	return "Hello !"
}
func sayByeBye() string {
	return "Bye Bye !"
}
func main() {
	wrapping(sayHello)
	wrapping(sayByeBye)
}
/*
输出:
do my work...
wrapping function:  Hello !
my work finished !
do my work...
wrapping function:  Bye Bye !
my work finished !
*/
go语言中new和make是内置函数,主要用来创建分配类型内存。
new(T)创建一个没有任何数据的类型为T的实例,并返回该实例的 指针;
make(T,args) 只能创建slice,map,channel,并返回一个有初始值args(非零)的T类型的实例,非指针。
二者都是内存的分配(堆上),但是make只用于slice、map、channel的初始化,而new用于类型的内存分配,并且内存内置为0.
make返回的还是这三个引用类型本身;而new返回的是指向类型的指针。
        slice和array接近,不过更加的灵活,可以在新的元素加入的时候增加长度。slice总是指向底层的一个array。slice是一个指向array的指针,这是其与array不同的地方;slice是引用类型,这意味着当赋值某个slice到另外一个变量,两个引用会指向同一个array。 例如,如果一个函数需要一个slice参数,在其内对slice元素的修改也会体现在函数调用者中,这和传递底层的array指针类似。
    
        append: 向slice追加零值或者其他的x值,并且返回追加后的新的slice。如果原来的slice没有足够的容量,那么append会分配一个足够大的,新的slice来存放原来的slice和后面追加的值。因此返回的slice可能和原来的不是指向同一个array
Slice 所允许申请的最大容量大小,与当前值类型和当前平台位数有直接关系
slice扩容机制
1.如果切片的容量小于1024个元素,那么扩容的时候slice的cap就翻番,乘以2;一旦元素个数超过1024个元素,增长因子就变成1.25,即每次增加原来容量的四分之一。
2.如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组。
make创建
         
    length 表示slice中已经使用的数据长度
 
    capacity 表示slice中指针执行的数组容量,如果缺省capacity 和length大小相等
make([]T, length, capacity)  
    slice1 := make([]T, length)

常用的感觉就是闭包和go func协程了,再说吧。。。。。
go中没有extends关键字,所以没有原生级别的继承。go本质上是使用interface实现的,是使用组合来实现继承,用组合来代替继承。
在go的结构体struct,通过匿名成员的方式实现继承,比如,Student继承了Men
type Men struct {
    name string
    age int
}
 
type Student struct {
    Men
    score int
}
对于接口interface,通过直接引入另一接口的方式实现继承,比如,ReadWriter继承了Reader和Writer
type Reader interface {
}
 
type Writer interface {
}
 
type ReadWriter interface {
	Reader
	Writer
}
实现代码解耦
goroutine + channel数据共享
!评论内容需包含中文