golang基础篇
Posted fengzaoye
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang基础篇相关的知识,希望对你有一定的参考价值。
一、切片:
1、主要看指针指向位置
比如 一个切片 var s []int{1,2,3,4,5,6,7}
指针指向0位
长度是 7 ,容量是7
a := s[2:4]
指针指向index为2为
a 长度是 2 (元素是2,3) 容量是5 (从index为2往右算或者max_len 减去 开始index,即 7 -2 = 5
二、defer
延迟处理
执行机制: 在函数内先实例(这在defer函数里包含函数参数有用,比如 defer func(int,int,func()),先执行里面的func),然后待执行完函数后,多个defer再按照
LIFO(后进先执行)原则执行。
还有一点需要注意,defer在实例时,它的参数是已确定,比如在defer前面定义了参数a = 1,在defer 后面再重新赋值a = 10,在执行defer时是按a=1传进defer的。
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
y = 20
fmt.Println("dfdff")
}
三、指针
&在变量前,取的是指针变量(即内存地址)
如
a := 10
b := &a //获取到a变量的内存地址,类型是 int的指针类型: *int
c := b //通过对指针变量进行取值操作,获取指针变量指向的原变量的值
关键字 new , make
new : func new(Type) *Type
在声明类型指针变量时,因为为引用类型,所以需要初始化后才有内存空间,才能进行赋值
var a *int
a = new(int)
*a = 10
fmt.Println(a)
make: func make(t Type, size ...IntegerType) Type
make只适用slice、map、chan
make函数是无可替代的,我们在使用slice、map以及channel的时候,都需要使用make进行初始化,然后才可以对它们进行操作。
func main() {
var b map[string]int
b = make(map[string]int, 10)
b["沙河娜扎"] = 100
fmt.Println(b)
}
new与make的区别:
1、二者都是用来做内存分配的。
2、make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
3、而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。
四、结构体(struct)
type 类型名 struct {
字段名 字段类型
字段名 字段类型
…
}
结构体本身也是一种类型,我们可以像声明内置类型一样使用var关键字声明结构体类型。
基本例子:
type person struct { name string city string age int8 } func main() { var p1 person p1.name = "沙河娜扎" p1.city = "北京" p1.age = 18 fmt.Printf("p1=%v ", p1) //p1={沙河娜扎 北京 18} fmt.Printf("p1=%#v ", p1) //p1=main.person{name:"沙河娜扎", city:"北京", age:18} } 可以通过使用new关键字对结构体进行实例化,得到的是结构体的地址。 格式如下: var p2 = new(person) fmt.Printf("%T ", p2) //*main.person fmt.Printf("p2=%#v ", p2) //p2=&main.person{name:"", city:"", age:0} p2是一个结构体 Go语言中支持对结构体指针直接使用.来访问结构体的成员。 var p2 = new(person) p2.name = "小王子" p2.age = 28 p2.city = "上海" fmt.Printf("p2=%#v ", p2) //p2=&main.person{name:"小王子", city:"上海", age:28} p2.age = 28 其实在底层是(p2).age = 28,这是go语言帮助我们实现的语法糖。
五、构造函数
Go语言的结构体没有构造函数,我们可以自己实现。 例如,下方的代码就实现了一个person的构造函数。 因为struct是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以该构造函数返回的是结构体指针类型。
func newPerson(name, city string, age int8) *person { return &person{ name: name, city: city, age: age, } } 调用构造函数 p9 := newPerson("张三", "沙河", 90) fmt.Printf("%#v ", p9) //&main.person{name:"张三", city:"沙河", age:90}
六、方法
方法是一种作用于特定类型变量的函数,类似其他语言的this或self,定义如下:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
函数体
}
一般接收者变量名是接收类型的名字首位小写,如结构体Person,它的接收者名为p。
例子:
//Person 结构体 type Person struct { name string age int8 } //NewPerson 构造函数 func NewPerson(name string, age int8) *Person { return &Person{ name: name, age: age, } } //Dream Person做梦的方法 func (p Person) Dream() { fmt.Printf("%s的梦想是学好Go语言! ", p.name) } func main() { p1 := NewPerson("小王子", 25) p1.Dream() }
方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。
七、channel
channel 是遵循FIFO原则,有个例子,当配合goroutine(开线程)使用,多个channel读取时,会实时根据当前读取的cha1,cha1存多少被读取的就有多少。
例子:
`package main import( "fmt" "time" ) func recv(ch chan int) { for i := 0;i<3;i++ { fmt.Println(i) time.Sleep(time.Second) ch <- i //传送值给cha1 } close(ch) fmt.Println("ppppppp") } func recv2(ch1 chan int,ch2 chan int) { for { tmp,ok := <-ch1 fmt.Println(tmp) if !ok{ break } ch2 <- tmp*tmp } close(ch2) fmt.Println("kkssk") } func main() { cha1 := make(chan int, 100) //初始化一个channel cha2 := make(chan int, 200) // 初始化另一个channel go recv(cha1) go recv2(cha1, cha2) for tt := range cha2 { fmt.Println(tt) } }`
待续~
以上是关于golang基础篇的主要内容,如果未能解决你的问题,请参考以下文章