首页 > 技术文章 > golang学习

fengzaoye 2020-07-21 15:12 原文

切片:

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

2、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")
}

3、指针

&在变量前,取的是指针变量(即内存地址)

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用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

4、结构体(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\n", p1)  //p1={沙河娜扎 北京 18}
	fmt.Printf("p1=%#v\n", p1) //p1=main.person{name:"沙河娜扎", city:"北京", age:18}
}

可以通过使用new关键字对结构体进行实例化,得到的是结构体的地址。 格式如下:
var p2 = new(person)
fmt.Printf("%T\n", p2)     //*main.person
fmt.Printf("p2=%#v\n", 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\n", p2) //p2=&main.person{name:"小王子", city:"上海", age:28}
p2.age = 28 其实在底层是(p2).age = 28,这是go语言帮助我们实现的语法糖。

5、构造函数
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\n", p9) //&main.person{name:"张三", city:"沙河", age:90}

6、方法
方法是一种作用于特定类型变量的函数,类似其他语言的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语言!\n", p.name)
	}

	func main() {
		p1 := NewPerson("小王子", 25)
		p1.Dream()
	}

7、包定义以及导入使用
包的定义:
定义一个包(文件夹),文件夹下go文件首行:package 包名(和文件夹同名)
导入:
import "路径/包名"
例子:
如定义一个包: github.com目录下文件夹 kk 下go文件
package kk
import (
"fmt"
)
type Data struct {
id int
name string
}

注意: 这里命名需要注意,首字母为大写才可以被外部调用!!

导入:
import (
"github.com/kk"
)

a := kk.Data

#####################################################################################

推荐阅读