Go语言学习笔记

此笔记是本人在学习Go语言过程中对知识点进行记录,以方便之后查阅学习,如果有不合理的地方欢迎各位大佬指出!
1.变量

  • 使用var关键字
var a,b,c bool            //定义
var c string = "helllo"   //赋值     
  • 既可以在函数体内,也可以在包内
  • 使用var()进行集中定义变量
  • 编译器可以自动判断变量类型,可以不写 变量的类型
  • 可以使用:=的方式定义变量。但是这种方式只能在函数体内使用,在变量初始化时使用

2.变量类型

  • (u)int 没有规定长度,根据操作系统位数自行决定
    (u)int8 (u)int16 (u)int32 (u)int64 uintptr 指针
  • bool string
  • byte
  • rune (char类型,32位)
  • float32 float64
  • complex64 complex128(复数类型)
  • 变量类型转换是强制的,没有隐式转换

3.常量

  • 常量用const关键字
  • 可以定义类型,也可以不定义类型,不定义类型时常量可以当做任何类型使用

4.特殊的常量----------枚举类型

  • 普通枚举类型
  • 自增值枚举类型 iota

5.条件语句
if条件中可以赋值

6.switch语句会自动添加break语句,除非使用fallthrough,最后的默认情况使用default panic。switch中也可以没有语句,直接放到case中

7.for循环
和其他语言的区别在于省略掉小括号,同时初始条件、自增条件以及所有的条件都可以不写,这样是一个死循环

8.Go语言中只有值传递,没有引用传递,但是可以利用指针达到类似引用传递的效果

9.指针

  • 变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址
  • 一个简单的例子说明:ptr := &v ,假设变量v的类型为T,则变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为T,称做 T 的指针类型,*为指针
  • 取地址操作符&和取值操作符* 是一对互补操作符,&取出地址,*根据地址取出地址指向的值。
    变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
    1)对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
    2)指针变量的值是指针地址。
    3)对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。
    * 操作符根本意义就是操作指针指向的变量。当操作在赋值操作符右值时,就是取指向变量的值,当操作在赋值操作符左值时,就是将值设置给指向的变量。

10.数组

  • 数量写在类型前面
  • 数组的遍历可以使用range返回两个参数:数组下标和对应下标的值
  • 使用下划线_可以将变量省略,不止在数组中其他所有地方都可以
  • [20]int和[30]int 是不同的类型

11.Slice
关于切片可以参考以下链接:slice入门
slice初始化的问题可以参考以下链接:slice初始化

12.Map

  • 形式为map[key] value
  • 创建
m := make(map[string] string)
n := map[string] string {
  "cat" : "wanwan",
  "dog" : "baibai",
  "language" : "Chinese",
  "country" : "China",
}
  • 获取value值,直接使用m[key]
  • 当map的key值不存在时,不会报错
  • 判断key是否存在时,可以用value,ok = m[key]
  • delete(key)可以直接删除对应的value
  • map的遍历使用range

13.结构体struct

  • struct的定义
type treeNode struct {
	value int
	right,left *treeNode
}
  • struct的创建
var root treeNode
root = treeNode{value : 3}
root.right =&treeNode{}
root.left = &treeNode{5,nil,nil}
root.right.left = &treeNode{8,nil,nil}
root.left.right = new(treeNode)
root.right.right = createTreeNode(7)
  • go语言中没有构造函数,但是可以通过工厂函数达到类构造函数的效果
func createTreeNode(v int) *treeNode {
	return &treeNode{
	value:v
	}
}
  • 结构体中的方法定义及使用
    func (recevier type ) methodName(参数列表)(返回值列表){}
func (node *treeNode) setValue (value int) {
	node.value = value
}
root.right.setValue(12)

注意:struct中的方法接收者的类型可以是值类型,也可以是指针类型,但是只有指针类型才会改变值。而且,在调用方法时自动做了优化处理对传入的指针和值进行处理

  • nil指针也可以调用方法,但是需要加return
  • 值接收者可以接受值/指针接收者

14.封装

  • 首字母小写:private
  • 首字母大写:public

15.包

  • 每个目录一个包
  • 结构体定义的方法必须放在一个包内,但可以是不同的文件
  • main包包含可执行入口

在练习包和封装时,出现了无法导入工程中的包,我使用的IDE是idea,在另一个文件中使用另一个包的函数时,只需要包名.方法即可使用,并且会自动import相应的包名,但是我的毫无反应,经过多次度娘寻求帮助,最后发现时GoROOT配置错误,它的配置可以具体参考如下这篇博客,很详细
Intellij IDEA创建Go工程

16.官方推荐:所有项目和第三方库都放在同一个GOPATH下
也可以将每个项目放在不同的GOPATH下
1)go get下载第三方库
2)gopm来获取无法下载的包
3)安装gopm命令:

go get github.com/gpmgo/gopm

有时候去遇到网站可以打开,但是go get一直不动的状态,还没有找到解决的办法
执行完此条命令后,会在bin目录下生成gopm.exe
4)接下来可以运行以下指令

gopm get -g -v -u golang.org/x/tools/cmd/goimports

在下载的过程中,有时会出现缺少某些包的情况,只需要在对应的路径下下载相应的包即可解决问题
5)

go build golang.org/x/tools/cmd/goimports

会在bin文件夹中生成imports的exe,go install有时不好使,只需要使用go build即可

17.Go中每个目录下面都有一个main文件,如果每个目录下有多个main函数,则无法编译成功

18.接口
Go语言中没有继承和多态,这些是通过接口来实现的
1)duck typing的概念
描述事物的外部行为而非内部结构
严格来说go属于结构化类型系统,类似duck typing
2)实现者指明不需要实现某个接口,只需要实现接口中的方法,由使用者规定必须有接口中的方法
3)接口定义

type Retriever interface {
   Get (source string) string
}
func download(r Retriever) string{
   return r.Get("http://www.imooc.com")
}

4)接口的值类型

  • 接口变量自带指针
  • 接口变量同样采用值传递,几乎不需要使用接口的指针
  • 接口变量中包含两部分:一部分为实现者的类型,另一部分为实现者的值,或者是指向实现者的指针,具体是只还是指针,视具体情况而定,在实际使用中,一定不要使用接口变量的地址,因为本身接口变量有指针
  • 指针接收者实现只能以指针方式使用,值接收者都可以
  • 任何类型表示法:
interface{}
  • 查看接口变量类型
//type switch
switch v := r.(type) {
case baidu.Retriever: {
	fmt.Println("Contents:",v.Contents)
}
case *real.Retriever: {
	fmt.Println("UserAgent:",v.UserAgent)
}

//type assertion
if realRetriever,ok := r.(*real.Retriever); ok {
	fmt.Println(realRetriever.UserAgent)
}else {
	fmt.Println("not realRetriever")
}

-接口的组合

type Retriever interface {
	Get(url string) string
}

type Poster interface {
	Post(url string,
		form map[string] string) string
}

//组合接口
type RetrieverPoster interface {
	Retriever
	Poster
}
  • 常用的接口
    1)Stringer(类似于java中的tostring)
type Stringer interface {
	String() string
}

可以通过重写string方法实现Stringer接口
2)

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

19.函数式编程

  • 函数式一等公民:参数、变量、返回值都可以是函数
  • 高阶函数:函数传入的参数是函数
  • 闭包
    对于我来说,特别难理解的闭包:网上找到一个通俗易懂的概念
    闭包就是能够读取其他函数内部变量的函数,闭包可以简单理解成“定义在一个函数内部的函数“。
    所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

20.资源管理与出错处理

  • defer调用确保调用在函数结束时发生
  • 参数在defer语句时计算
  • defer列表为先进后出
    一种错误处理方式如下:
file,err := os.OpenFile(filename,os.O_EXCL|os.O_CREATE,0666)
err = errors.New("This is a custom error")  //自定义error
if err != nil {
	if pathError,ok := err.(*os.PathError); ok {
		fmt.Println(pathError.Err)
	}else {
		fmt.Printf("unkown error",err)
	}
}

21.panic

  • 停止当前程序执行
  • 一直向上返回,执行每一层的defer
  • 如果没有遇到recover,程序退出

22.recover

  • 仅在defer调用中使用
  • 获取panic的值
  • 如果无法处理,可重新panic

23.测试
测试的文件名可以命名为xxx_test

  • 测试代码示例
package main

import (
	"fmt"
	"math"
)

func calTriangle(a,b int) int {
	var c int
	c = int(math.Sqrt(float64(a*a+b*b)))
	return c
}

func triangle() {
	var a,b int = 3,4
	fmt.Println(calTriangle(a,b))
}

func main() {
	triangle()
}

package main

import (
	"testing"
)
//测试代码,注意此处的测试代码的函数名开头必须为Testxxx,系统方可识别
func TestTriangle**(t *testing.T) {
	tests := []struct{a,b,c int} {
		{3,4,5},
		{5,12,13},
		{8,15,17},
		{12,15,19},
	}
	for _, v:= range tests {
		if actual := calTriangle(v.a,v.b); actual != v.c {
			t.Errorf("calTriangle(%d,%d);"+
				"got %d; expected %d",
				v.a,v.b,actual,v.c)
		}
	}
}
  • 系统能够自动识别test代码,从而可以正常运行,进入该测试程序所在的目录,执行命令go test 获得测试结果
  • 测试程序也可以获得测试代码的覆盖率,如下图所示:
    Go语言学习笔记_第1张图片
    通过命令行执行指令go test -coverprofile=c.out,也可以得到代码覆盖率,如下图所示:
    在这里插入图片描述
    当然,也可以借助浏览器查看哪些被覆盖到,哪些没有被覆盖到,只需要在命令行执行以下命令:
go tool cover -html=c.out

此时,将跳转到浏览器界面,如下图所示:
Go语言学习笔记_第2张图片

  • 测试代码性能示例如下:
func BenchmarkDupStr(b *testing.B) {
	s := "黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"
	a := 8

	for i:=0;i

代码性能测试结果如下:
Go语言学习笔记_第3张图片
同样,通过终端输入以下命令也可以得到类似的结果

go test -bench .

你可能感兴趣的:(Go语言学习笔记)