打包和工具链
包
包名惯例
给包命的惯例是使用包所在目录的名字
因导入包时使用的是全路径,因此并不需要所有的名字都与别的包不同
main 包
程序编译时,会使用声明main 包的代码所在的目录的目录名作为二进制可执行文件的文件名
导入
远程导入
命名导入
导入的两个包的名字相同,可以命令一个别名代替一个包的名字,示例如下:
import (
"fmt"
myfmt "myfmt/fmt"
)
func mian() {
fmt.Println("Standard Library")
my.fmt.Println("mylib/fmt")
}
空白标识符
下划线,用来抛弃不想继续使用的值,如给导入的包赋予一个空名字,或者忽略函数返回的不感兴趣的值
函数 init
使用go工具
go build hello.go 编译hello.go文件
go clean hello.go 删除编译生成的可执行文件
示例:使用io包工作
package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/goinaction/code/chapter3/words"
)
func mian() {
filename := os.Args[1]
contents,err := iouttil.ReadFile(filename)
if err != nil {
return
}
text := string(contents)
context := words.CountWords(text)
fmt.Printf("There are %d words in your text. \n",count)
}
go run hello.go 编译执行hello.go文件
go vet hello.go 检测代码的常见错误
Printf类函数调用时,类型匹配错误的参数
定义常用的方法时,方法签名的错误
错误的结构标签
没有指定字段名的结构字面量
go代码格式化
go fmt hello.go 将hello.go文件到中的代码进行格式化
go语言文档
从命令行获取文档
go doc tar 查看archive/tar包的相关资料
浏览文档
godoc -http=:6060 启动web查看文档
依赖管理
第三方依赖
数组、切片和映射
数组的内部实现和基础功能
数组是切片和映射的基础数据结构
数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块
声明和初始化
//声明一个数组,并设置为零值
//声明一个包含5个元素的整型数组
var array [5]int
//使用数组字面量声明数组
//声明一个包含5个元素的整形数组
//用具体值初始化每个元素
array := [5]int{10,20,30,40,50}
//让go自动计算声明数组的长度
//声明一个整形数组
//用具体值初始化每个元素
//容量由初始化值得数量决定
array := [...]int{10,20,30,40,50}
//声明数组并指定特定元素的值
//声明一个有5个元素的数组
//用具体值初始化索引为1和2的元素
//其余元素保持零值
array := [5]int{1:10,2:20}
使用数组
//访问数组元素
//声明一个包含5个元素的整形数组
//用具体值初始化为每一个元素
array := [5]int{10,20,30,40,50}
//修改索引为2的元素的值
array[2] = 35
//使用*运算符就可以访问元素指针所指向的值
//访问指针数组的元素
//声明包含5个元素的指向整数的数组
//用整型指针初始化索引为0和1的素组元素
array := [5]*int{0:new(int),1:new(int)}
//为索引为0和1的元素赋值
*array[0] = 10
*array[1] = 20
//把同样类型的一个数组赋值给另一个数组
//声明第一个包含5个元素的字符串数组
var array1 [5]string
//声明第二个包含5个元素的字符串数组
//用颜色初始化数组
array2 := [5]string{"Red","Blue","Green","Yellow","Pink"}
//把array2的值复制倒array1
array1 = array2
类型相同的数组
数组的长度和每个元素的类型都相同
类型不同的数组不能互相赋值
//复制数组指针,只复复制指针的值,而不会复制指针所指向的值
//把一个指针数组赋值给另一个
//声明第一个包含3个元素的指向字符串的指针数组
var array1 [3]*string
//声明第二个包含3个元素的指向字符串的指针数组
//使用字符串指针初始化这个数组
array2 := [3]*string{new(string),new(string),new(string)}
//使用颜色为每个元素赋值
*array2[0] = "Red"
*array2[1] = "Blue"
*array2[2] = "Green"
//将array2复制给array1
array1 = array2
多维数组
声明二维数组
//声明一个二维数组,两个维度分别存储4个元素和2个元素
var array [4][2]int
//使用数组字面量来声明并初始化一个二维整型数组
array := [4][2]int{{10,11},{20,21},{30,31},{40,41}}
//声明并初始化外层数组中索引为1个和3的元素
array := [4][2]int{1:{20,21},3:{40,41}}
//声明并初始化外层数组和内层数组的单个元素
array := [4][2]{1:{0:20},3:{1:41}}
//访问二维数组的元素
//声明一个2x2的二位整型数组
var array [2][2]int
//设置每个元素的整型值
array[0][0] = 10
array[0][1] = 20
array[1][0] = 30
array[1][1] = 40
//同样类型的多维数组赋值
//声明两个不同的二维整型数组
var array1 [2][2]int
var array2 [2][2]int
//为每个元素赋值
array2[0][0] = 10
array2[0][1] = 20
array2[1][0] = 30
array2[1][1] = 40
//将array2的值复制给array1
array1 = array2
//使用索引为多维数组赋值
//将array1的索引为1的维度复制到一个同类型的新数组里
var array3 [2]int = array1[1]
//将外层数组的索引为1,内层数组的索引为0的整型值复制到新的整型变量里
var value int = array1[1][0]
在函数间传递数组
//使用值传递,在函数间传递大数组
//声明一个需要8MB的数组
var array [1e6]int
//将数组传递给函数foo
foo(array)
//函数foo接受一个100万个整型值的数组
func foo(array [1e6]int) {
...
}
//使用指针在函数间传递大数组
//分配一个需要8MB的数组
var array [1e6]int
//将刷u在的地址传递给函数foo
foo(&array)
//函数foo接受一个指向100万个整型值得数组的指针
func foo(array *[1e6]int) {
...
}
切片不的内部实现和基础功能
切片是一种数据结构,该数据结构便于使用和管理数据集合
依据动态数组的概念构建,可以按需自动增长和缩小
内部实现
切片的3个字段的数据结构
指向底层数组的指针,切片访问的元素个数(即长度),切片允许增长到的元素个数(即容量)
创建和初始化
make和切片字面量
//使用长度声明一个字符串切片
//创建一个字符串切片
//其长度和容量都是5个元素
slice := make([]string,5)
//使用长度和容量声明整型切片
//创建一个整型切片
//其长度为3个元素,容量为5个元素
slice := make([]int,3,5)
//通过切片字面量来声明切片
//创建字符串切片
//其长度和容量都是5个元素
slice := []string{"Red","Blue","Green","Yellow","Pink"}
//创建一个整型切片
//其长度和容量都是3个元素
slice := []int{10,20,39}
//使用索引声明切片
//创建字符串切片
//使用空字符串初始化第100个元素
slice := []string{99:""}
//声明数组和声明切片的不同
//创建有3个元素的整型数组
array := [3]int{10,20,30}
//创建长度和容量都是3的整型切片
slice := []int{10,20,30}
nil和空切片
//创建nil切片
//创建nil整型切片
var slice []int
//声明空切片
//使用make创建空的整型切片
slice := make([]int,0)
//使用切片字面量创建空的整型切片
slice := []int{}
使用切片
赋值和切片
//使用切片字面量来声明切片
//创建一个整型切片
//其容量和长度都是5个元素
slice := []int{10,20,30,40,50}
//改变索引为1的元素的值
slice[1] = 25
//使用切片创建切片
//创建一个整型切片
//其长度和容量都是5个元素
slice := []int{10,20,30,40,50}
//创建一个新切片
//其长度为2个元素,容量为4个元素
newSlice := sice[1:3]
//如何计算长度和容量
//对底层数组容量是k的切片slice[i:j]来说
长度:j - i
容量:k - i
//修改切片内容可能导致的结果
//创建一个整型切片
slice := []int{10,20,30,40,50}
//创建一个新切片
//其长度是2个元素,容量是4个元素
newSlice := slice[1:3]
//修改newSlice索引为1的元素
//同时也修改了原来的slice的索引为2的元素
newSlice[1] = 35
//表示索引越界得语言运行时错误
//创建一个整型切片
//其长度和容量都是5个元素
slice := []int{10,20,30,40,50}
//创建一个新切片
//其长度为2个元素,容量为4个元素
newSlice := slice[1:3]
//修改newSlice索引为3得元素
//这个元素对newSlice来说并不存在
newSlice[3] = 45
//会报超出索引错误
切片增长
//使用append向切片增加元素
//创建一个整型切片
//其长度和容量都是5个元素
slice := []int{10,20,30,40,50}
//创建一个新切片
//其长度为2个元素,容量为4个元素
newSlice := slice[1:3]
//使用原有的容量来分配一新元素
//将新元素赋值为60
newSlice = append(newSlice,60)
//若切片的底层数组没有足够的可用容量,append函数会创建一个新的底层函数,
//将被引用的现有的值复制到新数字组里,再追加新的值
//使用append同时增加切片的长度和容量
//创建一个整型切片
//其长度和容量都是4个元素
slice := []int{10,20,30,40}
//向切片追加一个新元素
//将新元素复制为50
newSlice := append(slice,50)
//newSlice是一个新的数组,其容量是slice的两倍
创建切片时的3个索引
//使用切片字面量声明一个字符串切片
//创建字符串切片
//其长度和容量都是5个元素
source := []string{"Apple","Orange","Plum","Banana","Grape"}
//使用3个索引创建切片
//将第三个元素切片,并限制容量
//其长度为1个元素,容量为2个元素
slice := source[2:3:4]
//如何计算长度和容量
slice[i:j:k]
长度:j - i
容量:k - i
//强制使用append创建一个新数组,切片更改元素在新数组上进行,避免改动原数组
//设置长度和容量一样的好处
//创建字符串切片
//其长度和容量都是5个元素
source := []string{"Apple","Orange","Plum","Banana","Grape"}
//对第三个元素做切片,并限制容量
//其长度和容量都是一个元素
slice := source[2:3:3]
//向slice中追加新字符串
slice = append(slice,"Kiwi")
//使用...可以将一个切片的所有的元素追加到另一个切片里
//将一个切片追加到另一个切片
//创建两个切片,并分别用两个整数进行初始化
s1 := []int{1,2}
s2 := []int{3,4}
//将两个切片追加在一起,并显示结果
fmt.Printf("%v\n",append(s1,s2...))
迭代切片
//使用for range迭代切片
//创建一个整型切片
//其长度和容量都是4个元素
slice := []int{10,20,30,40}
//迭代每一个元素并显示其值
for index,value := range slice {
fmt.Printf("Index: %d Value: %d\n",index,value)
}
//range会创建每个元素的副本,不是直接返回对该元素的使用
//使用空白标识符(下划线)来忽略索引值
//创建一个整型切片
//其长度和容量都是4个元素
slice := []int{10,20,30,40}
//迭代每个元素,并显示其值
for _,value := range slice {
fmt.Printf("Value: %d\n",value)
}
//使用传统的for循环对切片进行迭代
//创建一个整型切片
//其长度和容量都是4个元素
slice := []int{10,20,30,40}
//从第三个元素开始迭代每个元素
for index := 2;index < len(slice);index ++ {
fmt.Printf("Index: %d Value: %d\n",index,slice[index])
}
多维切片
//声明多维切片
//创建一个整型切片
slice := [][]int{{10},{100,200}}
//组合切片的切片
//创建一个整型切片的切片
slice := [][]int{{10},{100,200}}
//为第一个切片追加值为20的元素
slice[0] = append(slice[0],20)
在函数间传递切片
//在函数间传递切片
//分配包含100万个整型值得切片
slice := make([]int,1e6)
//将slice传递到函数foo
slice = foo(slice)
//函数foo接收一个整型切片,并返回这个切片
func foo(slice []int) []int {
...
return slice
}
映射的内部实现和基础功能
映射是一种数据结构,用于存储一系列无序的键值对
能够基于键快速检索数据
内部实现
映射是无序集合,但可以使用类似处理数组和切片的方式迭代映射钟的元素
不能预测键值对被返回的顺序
创建和初始化
//使用make声明映射
//创建一个映射,键的类型是string,只的类型是int
dict := make(map[string]int)
//创建一个映射,键和值都是string
//使用两个键值来初始化映射
dict := map[string]string{"Red":"#da1337","Orange":"#e95a22"}
//声明一个存储字符串切片的映射
//创建你一个映射,使用字符串切片的映射
dict := map[int] []string{}
使用映射
键值对赋值给映射,是通过指定适当类型的键并给这个键赋一个值
//为映射赋值
//创建一个空映射,用来存储颜色以及颜色对应的十六进制代码
colors := map[string]string{}
//将Red的代码加入到映射
colors["Red"] = "#da1337"
//从映射获取值并判断键是否存在
//获取键Blue对应的值
value,exists := colors["Blue"]
//这个键存在吗?
if exists {
fmt.Print(value)
}
//从映射获取值,并通过该值判断键是否存在
//获取键Blue对应的值
value := colors["Blue"]
//这个键存在吗?
if value != "" {
fmt.Println(value)
}
//使用range迭代映射
//创建一个映射,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"AliceBlue": "#f0F8ff",
"Coral": "#ff7F50",
"DarkGray": "#a9a9a9",
"ForestGreen": "#228b22",
}
//显示映射里的所有颜色
for key,value := range colors {
fmt.Printf("Key: %s Value: %s\n",key,value)
}
//从映射中删除一项
//删除键为Coral的键值对
delete(colors,"Coral")
//显示映射里的所有颜色
for key,value := range colors {
fmt.Printf("Key: %s Value: %s\n",key,value)
}
在函数间传递映射
//在函数间传递映射
func main() {
//创建一个映射,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"AliceBlue": "#f0F8ff",
"Coral": "#ff7F50",
"DarkGray": "#a9a9a9",
"ForestGreen": "#228b22",
}
//显示映射里的所有颜色
for key,value := range colors {
fmt.Printf("Key: %s Value: %s\n",key,value)
}
//调用函数来移除指定的键
removeColor(colors,"Coral")
//显示映射里的所有颜色
for key,value := range colors {
fmt.Printf("Key: %s Value: %s\n",key,value)
}
}
//removeColor 将指定的映射里的键删除
func removeColor(colors map[string]string,key string) {
delete(colors,key)
}
go语言的类型系统
用户定义的类型
//声明一个结构类型
//user 在程序里定义一个用户类型
type user struct {
name string
email string
ext int
privileged bool
}
//使用结构类型声明变量,并初始化为其零值
//声明 user类型的变量
var bill user
//使用结构字面量来声明一个结构类型的变量
//声明 user类型的变量,并初始化所有字段
//短变量声明
lisa := user{
name: "Lisa",
email: "lisa@email.com",
ext: 123,
privileged: true,
}
//使用结构字面量创建结构类型的值
//结构字面量声明
user{
name: "Lisa",
"email": "lisa@email.com",
ext: 123,
privileged: true,
}
//不使用字段名,创建结构类型的值
//声明user类型的变量
lisa := user{"Lisa","lisa@email.com",123,true}
//使用其他结构类型声明字段
//admin 需要一个user类型作为管理者,并附加权限
type admin struct {
person user
lever string
}
//使用结构字面量来创建字段的值
//声明 admin 类型的变量
fred := admin{
person: user{
name: "Lisa",
email: "lisa@email.com",
ext: 123,
privileged: true,
},
level:"super",
}
Go语言实战--笔记1
最新推荐文章于 2021-11-15 19:52:04 发布
3532

被折叠的 条评论
为什么被折叠?



