Go语言简单学习

时间:2021-03-01 21:14:20

GO

支持goroutine 和通道,并且推荐使用消息而不是共享内存来进行并发编程,总体来说,Go语言是一个非常现代化的语言,精小但非常强大

Go语言的主要特性:

1、自动垃圾回收

2、更丰富的内置类型

3、函数多返回值

4、错误处理

5、匿名函数和闭包

6、类型和接口

7、并发编程

8、反射

9、语言交互性

Go语言简单学习

Go语言的基础组成部分:

包声明

引入包

函数

变量

语句 &
表达式

注释

标识符(包括常量,变量,类型,函数名,结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的public
);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的protected)

go语言不能把大括号单独放一行,会错误

go
层序可以由多个标记组成,可以是关键字,标识符,常量,字符串,符号、如以下Go语句由6个标记组成

----标识符:用来命名变量、类型等程序实体、一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字
(0~9)
、下划线组成的序列,但是第一个子符必须是字母或下划线而不能是数字

----程序一般由关键字、变量、常量、运算符、类型和函数组成

程序中可能会使用到这些分割符:括号()
中括号[]
和大括号{}

程序中可能会使用到这些标点符号:

----go
语言中变量的声明必须使用空格隔开

go语言数据类型:在go编程语言中,数据类型用于声明函数和变量

数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时侯需要用大数据的时侯才去申请大内存,就可以充分利用内存

go语言有以下数据类型:

1、bool
布尔类型的值可以是常量true
或者 flase
一个简单的例子 var
b bool = true

2、数字类型:整形
int
和浮点型 float64
,go语言支持整形和浮点型数字,并且原生支持复数,其中位运算采用补码

3、字符串类型:字符串就是一串固定长度的子符连接起来的子符序列,go的子符串是由单个字节连接起来的,go语言的字符串的字节使用UTF-8
编码标识unicode
文本

4、派生类型

包括:指针类型(Pointer)、数组类型、结构化类型(struct)、channel类型、函数类型、切片类型

接口类型(interface)、Map类型

----数字类型:

Go也有基于结构的类型,例如:int、uint、uintptr

Go语言简单学习

go 语言变量

声明变量的一般形式是使用var
关键字:

var
indentifier (变量名)
type(类型)

Go语言简单学习

Go语言简单学习

值类型和引用类型

所有像int 、float 、 bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在在内存中的值:

当使用等号=将一个变量的值赋值给另一个变量时,如:j=i,实际上是在内存中将I 的值进行了拷贝:

你可以通过 &i
来获取变量 I
的内存地址,例如:0xf840000040
(每次的地址都可能不一样)。值类型的变量的值存储在栈中,内存地址会根据机器的不同而不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址,因为每台机器可能有不同的存储器布局,并且位置分配也可能不同

更复杂的数据通常会需要使用多个字节,这些数据一般使用引用类型保存

一个引用类型的变量
r1
存储的是 r1
的值所在的内存地址 (数字),或内存地址中第一个字所在的位置

这个内存地址为称之为指针,这个指针实际上也被存在另外的某一个字节中,同一个引用类型的指针指向的多个字节可以是在连续的内存地址中(内存布局是连续的)、这也是计算效率最高的一种存储形式;

也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址

这个内存地址称为指针,这个指针实际上也被存在另外的某一个字中

同一个引用类型的指针指向的多个字节可以是在连续的内存地址中(内存布局是连续的)、这也是计算效率最高的一种存储形式;

也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址

当使用赋值语句
r2
= r1 时,只有引用(地址)被复制

如果r1
的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2
也会受到影响

简短形式,使用:=赋值操作符

我们知道可以在变量的初始化时省略变量的类型而由系统自动推断,声明语句写上var关键字其实是有些多余了,因此我们可以将它们简写为 a:= 50 或者 b:= false

a 和 b 的类型(int 和 bool) 将由编译器自动推断

这是使用变量的首选形式、但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值,使用操作符 := 可以高效地创建一个新的变量,称之为初始化声明

注意事项:

如果在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明,例如
:a
:= 20 就是不被允许的,编译器会提示错误no
new variables on left side of := 但是 a
= 20 是可以的,因为这是给相同的变量赋予一个新的值

如果你在定义变量a之前使用它,则会得到编译错误,undefinet
a

如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误,例如下面这个例子当中的变量a

Go语言常量

常量是一个简单值的标识符,在程序运行时,不会被修改的量

常量中的数据类型只可以是bool型,数字型,(整数型,浮点型和复数)和字符串型

常量的定义格式:

Go语言简单学习

Go语言简单学习

常量还可以用作枚举:

常量可以用len(),cap(),unsafe() 函数计算表达式的值,常量表达式中,函数必须是内置函数,否则编译不通过

Go语言简单学习

Go语言简单学习

位移

Go语言简单学习

Go语言简单学习

go 语言运算符

运算符用于在程序执行时执行数学或逻辑运算

Go语言内置的运算符有:

---算术运算符

+ - * / % ++ –

---关系运算符

== < > <= >=

---逻辑运算符

&& || !

---位运算符

& | ^ << >>

---赋值运算符

= += -= *= /= %= <<= >>= &= ^= |=

---其他运算符

& 返回变量存储地址

* 指针变量

运算符优先级:有些运算符有较高的优先级,二元运算符的运算方向均是从左至右,下表列出了所有运算符以及它们的优先级,由下至上代表优先级由高到低

Go语言简单学习

Go语言条件语句

条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为true 来决定是否执行指定语句,并在条件为false 的情况再执行另外的语句

下图展示了程序语言中条件语句的结构:

Go语言简单学习

go 语言提供了以下几种条件判断语句:

if语句 由一个布尔表达式后紧跟一个或多个语句组成、if。。。else 语句后可以使用可选的else语句,else语句中的表达式在布尔表达式值为false 时执行你可以在if 或 else if 语句中嵌入一个或多个 if 或 else if语句switch 语句用于基于不同条件执行不同动作select 语句类似于switch 语句,但是select 会随即执行一个可运行的case ,如果没有case 可运行,它将阻塞,直到有case 可运行

Go语言循环语句:

在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句

Go语言简单学习

for 循环:重复执行语句块

循环嵌套:在for循环中嵌套一个或多个for循环

循环控制语句:

break语句:经常用于中断当前for循环或跳出switch语句

continue语句:跳过当前循环的剩余语句,然后继续进行下一轮循环

goto语句:将控制转移到被标记的语句

无限循环:如果循环中条件语句永远不为false
则会进行无限循环,我们可以通过
for
循环语句中只设置一个条件表达式来执行无限循环

Go语言函数

函数是基本的代码块,用于执行一个任务

Go语言最少有个main()
函数

你看以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务

函数声明告诉了编译器函数的名称,返回类型,和参数

Go语言标准提供了多种可动用的内置的函数,例如
len()
函数可以接受不同类型参数并返回该类型的长度,如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回的数组中包含的元素个数

Go 语言函数的定义格式如下:

Go语言简单学习

func function_name ([paramter list]) [return_types]{………}

函数定义解析:

---func: 函数由 func 开始声明

---function_name : 函数名称,函数名和参数列表一起构成了函数签名

---parameter list :参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数,参数列表指定的是参数类型,顺序,及参数个数。参数是可选的,也就是说函数也可以不包含参数

---return_types : 返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下,return_types 不时必须的

---函数体:函数定义的代码集合

函数调用:当创建函数时,你定义了函数需要做什么,通过调用该函数来执行指定任务

函数调用,向函数传递参数,并返回值,例如:

Go语言简单学习

Go语言简单学习

函数返回多个值:

Go语言简单学习

Go语言简单学习

函数参数:

函数如果使用参数,该变量可称为参数的形参

形参就像定义在函数体内的局部变量

调用函数,可以通过两种方式来传递参数:

值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数

引用传递:引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数

默认情况下,Go语言使用的是值传递,即在调用过程中不会影响到实际参数

函数用法

函数作为值函数定义后可作为值来使用

闭包闭包就是匿名函数,可在动态编程中使用

方法方法就是一个包含了接受者的函数

Go语言简单学习

Go语言简单学习

Go语言变量作用域

作用域为已声明标识符所标识的常量、类型、变量、函数或包在源代码中的作用范围

Go语言中变量可以在三个地方声明:

---函数内定义的变量称为局部变量

---函数外定义的变量称为全局变量

---函数定义中的变量称为i形式参数

局部变量:在函数体内声明的变量称之为局部变量 ,它们的作用域只在函数体内,参数和返回值变量也是局部变量

Go语言简单学习

Go语言简单学习

全局变量:在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用全局辨两个可以在

任何函数中使用,

Go语言简单学习

Go语言简单学习

Go语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑

Go语言简单学习

Go语言简单学习

形式参数:形式参数会作为函数的局部变量来使用

Go语言简单学习

Go语言简单学习

初始化局部变量和全局变量

int    0

float32  0

pointer  nil

Go语言数组

Go语言提供了数组类型的数据结构

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串

或者自定义类型、相对于去声明number0,number1....and number99 的变量,使用数组形式number[0],number[1]......

更加方便且易于扩展、数组元素可以通过索引(位值)来读取(或者修改)、索引从0开始、第一个元素索引为0,

第二个索引为1、以此类推

Go语言简单学习

声明数组:

Go语言数组声明需要指定元素类型及元素个数,语法格式如下:

Go语言简单学习

Go语言简单学习

Go语言指针

Go语言中的指针是很容易学习的,Go语言中使用指针,可以更简单的执行一些任务,我们都知道变量是一种使用方便的

占位符,用于引用计算机内存地址,Go语言的取地址符是&,放到一个变量前使用就会相应变量的内存地址

Go语言简单学习

Go语言简单学习

什么是指针:一个指针变量指向了一个值的内存地址,类似于变量和常量,在使用指针前你需要声明指针

var   var_name   *var_type

变量  变量名    变量指针类型

使用指针:

---定义指针变量

---为指针变量赋值

---访问指针变量中指向地址的值

在指针类型前面加上 *  来获取指针所指向的内容

Go语言简单学习

Go语言简单学习

Go空指针

当一个被定义后没有分配到任何变量时,它的值为nil,nil 也称为空指针,nil 在概念上和其它语言的null,

None ,nil,NULL,一样,都代指零值或空值,一个指针变量通常缩写为ptr

Go语言简单学习

Go语言简单学习

Go语言结构体

Go语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型

结构体是一系列具有相同类型或不同类型的数据构成的数据集合

定义结构体:结构体定义需要使用 type 和 struct 语句、struct 定义一个新的数据类型,结构体中有一个或多个成员,

type 语句设定了结构体的名称、结构体的格式如下

Go语言简单学习

Go语言简单学习

访问结构体成员:如果要访问结构体成员,需要使用 "." 点号 操作符,格式为:

结构体.成员名

Go语言简单学习

Go语言简单学习

结构体作为函数参数:结构体可以像其它数据类型作为参数传递给函数

Go语言简单学习

Go语言简单学习

结构体指针:可以定义指向结构体的指针类似于其他指针变量

Go语言简单学习

Go语言简单学习

Go语言切片(Slice)

Go语言切片是对数组的抽象

Go数组的长度不可改变,在特定场景中这样的集合就不太适合,Go语言提供了一种灵活,功能强悍的内置类型切片(动态数组)、

与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大

定义切片:

可以声明一个未指定大小的数组来定义切片:

var identifile []type

切片不需要说明长度

使用make() 函数来创建切片

var slice1 []type = make([]type,len)

简写

slice1 := make([]type,len)

也可以指定容量,其中capacity 为可选参数

make([]T,length,capacity)

这里len 是数组的长度并且也是切片的长度

切片初始化

s := [] int{1,2,3}

直接初始化切片,[]表示是切片类型 ,{1,2,3} 初始化值依次是 1,2,3 其中cap = len = 3

s := arr[:]

初始化切片s是数组arr的引用

s := arr[startIndex:endIndex]

将arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片

s := arr[startIndex:]

缺省endIndex 时将表示一直到arr 的最后一个元素

s1 := s[startIndex:endIndex]

通过切片 s 初始化切片s1

s := make([]int,len,cap)

通过内置函数make() 初始化切片s,    []int 标识为其元素类型为int 的切片

len() 和 cap() 函数

切片是可索引的,并且可以由len() 方法获取长度

切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少

Go语言简单学习

Go语言简单学习

空(nil)切片:一个切片在未初始化之前默认为nil ,长度为0,

Go语言简单学习

Go语言简单学习

切片截取:可以通过设置上下限来设置截取切片

Go语言简单学习

Go语言简单学习

append() and copy()  function

如果想要增加切片容量,我们必须创建一个新的更大的切片并把原分片的内容拷贝过来

下面的代码描述了从拷贝切片的copy 方法和向切片追加新元素的 append 方法

Go语言简单学习

Go语言简单学习

Go语言范围 (Range)

Go语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素

在数组和切片中它返回元素的索引和索引对应的值,在集合中返回key-value 对应的 key 值

Go语言简单学习

Go语言简单学习

Go语言Map(集合)

Map 是一种无序的键值对的集合,Map 最重要的一点是通过key 来快速检索数据,key 类似于索引,指向数据的值

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它,不过,Map是无序的,我们无法决定它的返回顺序

这是因为Map 是使用hash 表来实现的

定义Map:可以使用内建函数 make 也可以使用 map关键字来定义 Map:

/*声明变量,默认 map 是 nil*/

var   map_variable   map[key_data_type]  value_data_type

/*使用 make 函数*/

map_variable := make(map[key_data_type]  value_data_type)

如果不初始化 map, 那么就会创建一个 nil   Map , nil map  不能用来存放键值对

Go语言简单学习

Go语言简单学习

delete() 函数

delet() 函数用于删除集合的元素,参数为map 和其对应的 Key

Go语言简单学习

Go语言简单学习

Go语言递归函数

递归:就是在运行的过程中调用自己

语法格式如下:

func recursion(){

  recursion()  /*函数调用自身*/

}

func main(){

  recursion()

}

Go 语言支持递归,但我们在使用递归时,开发者需要设置退出条件,否则递归将进入无限循环中

递归对于解决数学上的问题是非常有用的,就像计算阶乘,生成斐波那契数列等

阶乘:

Go语言简单学习

Go语言简单学习

斐波那契数列:

Go语言简单学习

Go语言简单学习

Go语言类型转换

类型转换用于将一种数据类型的变量转换为另外一种类型的变量,Go语言类型转换基本格式如下

type_name(expression)

type_nmae 为类型名,expression 为表达式

Go语言简单学习

Go语言简单学习

Go 语言接口

Go语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了

这些方法就是实现了这个接口

Go语言简单学习

Go语言简单学习

在上面的程序中,我们定义了一个接口Phone ,接口里面有一个方法 call() ,然后我们在 main() 函数里面定义了一个Phone类

型变量,并分别为之赋值为 NokiaPhone 和 Phone 然后调用 call() 方法

给接口增加参数:

Go语言简单学习

Go语言简单学习

Go 语言错误处理

Go语言通过内置的错误接口提供了非常简单的错误处理机制

error 类型是一个接口类型,这是它的定义:

type error interface {

  Error() string

}

我们可以在编码中通过实现error 接口类型来生成错误信息

函数通常在最后的返回值中返回错误消息,使用error.New 可以返回一个错误信息:

func Sqrt(f     float64) (float64,error) {

  if f < 0  {

  return 0,errors.New("math : square root of negative number")

  }  

}

在下面的例子中,我们在调用Sqrt 的时侯传递的一个复数,然后就得到了 non-nil 的 error 对象,将此对象与 nil 比较,结果为 true,

所以fmt.Println (fmt 包在处理 error 时会调用Error 方法)被调用,以输出错误

result,err := Sqrt(-1)

if err != nil{

  fmt.Println(err)

}

实例:

Go语言简单学习

Go语言简单学习

至此基础的Go语言就算完成了,

IDE 可以用GoLand 个人感觉挺好用,可以装一下 vim 插件 vim 的操作习惯就不需要改变了