Golang入坑总结上篇

Go语言入门学习总结

Go的强悍之处

  1. 拥有静态类型语言的安全与编译运行性能,也具备动态类型语言的开发维护的高效,简而言之:Go = C + Python;
  2. 引入包的概念,任何一个Go语言文件,都必须归属于一个包,否则无法编译运行;
  3. 自带垃圾回收机制,内存自动回收,不需要开发人员在代码中进行控制;
  4. 骨子里的并发,Go设计之初衷就是为了高效的利用服务器多核多CPU的强悍硬件性能,所以为了实现高并发,Go所幸自带并发,仅仅一个简单的关键字Go,便可实现并发,无需像其他语言一样引入扩展包;
  5. 建立管道通信机制,解决了多个goroutine之间通信的问题;
  6. 引入切片,defer的创新概念
  7. Go语言的核心特性就是SHARE

关于包(package)

包定义一组编译过的代码,包的名字类似命名空间,可以用来间接访问包内声明的标识符

  1. 每个包都在一个单独的目录里,包名使用所在目录的名字;
    2.任何Go语言编译的可执行程序都必须包含main包,它是整个程序执行的入口,下面创建一个简单的main函数:
package main

import "fmt"

func main()  {
	fmt.PrintIn("Hello World")
}
  1. 导包;
    导入多个包使用import,编译器会根据配置的GO环境变量去查找磁盘上的包
imp ort (
	"fmt"
	"string"
	...
)                   
	**远程导入**:由于目前分布式版本控制系统,可输入URL,远程导入一些特定的包,在导入的过程中会使用go get获取指定URL的包;
	**命名导入**:若导入的多个包具有相同的名字,可使用命名导入,左侧自定义包的名字,右侧为原始包名
// 命名导入
import (
	"fmt"
	myfmt "mylib/fmt"
)
  1. GOPATH环境变量决定了Go源代码在磁盘上保存,编译,安装的位置;
  2. 可以为 每个工程设置不同的GOPATH;

数组,切片,映射

数组

数组是最为基础的数据结构,切片以及映射都基于此,数组是一个长度固定,用于存储一段具有相同类型的元素的连续块
数据内部元素类型相同,且内存连续分配,因此速度很快

// 声明一个包含五个元素的整型数组
var arr [5]int
// 声明数组并初始化
arr := [5]int{1, 2, 3, 4, 5}
// 声明部分值,其余值为默认值0
arr := [5]int{1:1, 2:2}
// 给数组指定元素赋值
arr[2] = 3
// 数组之间的复制使用=即可实现
// 声明一个二维整型数组,分别存储4个元素和2个元素(多维数组)
var arr1 [4][2]int
arr2 := [4][2]{{1,2},{3,4},{5,6},{7,8}}
切片
  • 切片是基于动态数组的概念构建,可以按需自动增长和缩小的一种数据结构
  • 切片是对于对于底层数组的一个抽象
  • 切片三要素:指向底层数组的指针;切片访问元素的个数;切片容量
// 使用make函数创建声明一个切片,元素类型为string,长度为3,未设置容量
slice1 := make([]string,3)
// 给切片设置容量,切片长度大于容量会编译失败
slice2 := make([]string,3,5)
// 使用切片字面量
slice3 := []string{"1","2"}
// 使用索引
slice4 := []int{2:"ok"}
// 创建一个nil整型切片
var slice []int
// 使用切片,下面两个切片共享一个底层数组,一个切片变化,另一个切片会感知
newSlice = slice1[1:3]
// 切片增长,底层数组元素+1
newSlice = append(newSlice,"mabo")
// append函数智能化,切片容量小于1000时容量会成倍的增加
// 迭代切片,可以获取索引及其值
for index, value in range slice1 {
	...
}
映射

映射是一种存储一系列无序键值对的数据结构
映射能够基于键来快速检索数据
映射的底层实现是散列表,即哈希表

// 使用make函数创建一个映射
dict := make(map[string]int) // 该映射键为字符串类型,值为整型
// 使用映射字面量
dict := map[string]string{"name":"mabo","wife":"qiong"}
函数之间传递数组,切片,映射
  1. 数组:函数之间传递数组开销很大,因此传入该数组的指针;
  2. 切片:切片的尺寸很小,在函数间传递可直接使用值传递,非常快速,简单
  3. 映射:与切片一样,映射在函数之间传递时不会创建一个该值的副本,开销同样也很小,可直接传递

强悍的类型系统

// 声明类型
type user struct{
	name string
	email string
	ext int
	privileged bool
}
// 声明类型的变量
var mabo user 
james := user{
	name:"james",
	email:"james@163.com"
}
  • 可基于一个已有的类型声明新的类型,新声明的类型仍然是独立的类型!
  • 声明新的类型的方法之前,需要考虑使用值接收者还是指针接收者,当该类型是本质是原始的,那么使用值接收者声明方法,当该类型的本质是非原始的,则需要使用指针接收者声明方法。
方法

方法的作用是给类型添加行为,本质上也是函数,但在声明方面有所不同,需要确定值接收者或者指针接收者,同样地,当一个函数具备接收者,就称之为方法

func (mabo user) getAge(name string)(age int, err string) {}
类型的分类
  • 内置类型

    • 数值类型,字符串类型,布尔类型;
    • 将内置类型的值传递给方法或者函数时,应使用值传递的模式,即传递一个对应值的副本;
  • 引用类型

    • 切片,映射,通道,接口,函数均为引用类型;
    • 声明引用类型的变量时,称这些变量为标头值,标头值即为一个指向底层数据结构的指针,标头值专为复制而生,所以在使用这些变量的时候无需考虑共享,直接复制就OK啦!
    • type IP []byte // 声明了一个字节切片类型
  • 结构类型

    • 结构类型用来描述一组数据值,这组值的本质可以是原始的,也可以是非原始的;
    • 任何一个工厂函数返回了一个指针,代表这个返回值的本质是非原始的;
  • *接口类型
    接口是用来定义一组行为的类型,如果用户声明的类型变量实现了接口定义的方法,那么这个用户变量即实现了该接口,该用户定义的类型值可以赋予该接口类型的值
    多态:任何用户定义的类型的值或者指针理论上都可以实现接口定义的方法,所以我们说,接口具有多态性

    接口的数据结构

    1. 包含一个指向内部表的指针,内部表称之为iTable,包含所存储的值的类型信息以及与该值关联的一组方法,即方法集
    2. 指向所存储的值的指针;

    方法集

    • 定义了一组关联某个值或者指针的方法,并且定义了接口的接受规则;
    ValuesMethod Receivers
    T( t T)
    *T(t T)/(t *T)

    上面的表格形象的阐述了方法集的规则,当我们需要使用值来实现一个接口,对应地,我们只能使用值接收者去实现该接口定义的方法;使用指针实现一个接口,则对应的方法的接收者可以是值接收者,也可是是指针接收者

  • 嵌入类型

    • 为了实现代码复用,Go语言允许用户扩展或者修改已有类型的行为,那么,将已有的类型直接声明在新的结构类型里,形成了嵌套的一种结构,产生了外部类型与内部类型
    • 内部类型的相关的标识符会提升到外部,相当于直接声明到了外部一样,这样外部类型就整合了内部类型的所有属性,方法,外部类型也可以声明与内部类型相同的标识符来覆盖内部类型的字段或者方法(可理解为重写的概念)
type user struct{
	name string
	age int
}
type admin struct{
	user // 嵌入类型
	power string
}
- 内部类型有的外部类型也可以用了,也就是说,内部类型实现的接口,外部类型同样也实现了(外部类型:舒服。。。)
- 嵌入类型提供了Go语言强大的扩展能力,无需像其他语言一样使用继承!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值