go学习笔记

go学习笔记

初始go

异常处理的defer是个不错的特性,虽然说有人反驳说其中的java代码不够合理,但是这种方式确实对c是一个巨大的进步。
工程编译根据方便,没有Makefile文件,只要一个go命令即可。但是必须要设置GOPATH路径,这一步能省掉就更好了。


顺序编程

变量:
支持:int,字符串,数组,数组切片,结构体,指针,字典,函数指针。
iota:在每次const是初始化为0,每出现一次会自增1。

全局变量不支持类型推导——:=

go 的取反是^而不是~

float64相当于c中的double。

浮点数的比较不可以使用==,因为有精度问题。

字符串在go中是一种基本类型:

go中有两种字符类型:byte,其实就是uint8,代表utf-8的单个字节,另一个是rune,代表单个Unicode字符。

go的api多数假设字符串为utf-8编码。

go中的数组时值类型,作为函数参数是进行了一次的拷贝操作。函数无法修改入参的值。

var v [3][5]int = [3][5] int{{1,2},{3,4},{5,6}}//数组初始化

数组长度定义后无法修改,数组时值类型,每次传递产生一个副本。


数组切片
切片可以动态扩展空间(是不是无限制扩展?),随意传递而不会重复复制。

s := v[:]
s := v[:5]
s := v[5:]
s := v[1:5]
s := make([]int, 5)//5个元素
s := make([]int, 5, 10)//5个元素,存储能力为10
s := []int{1,2,3,4,5,6}


使用cap可以获得切片的存储能力,len可以获得切片的长度。
基于数组创建切片存储能力就是数组的大小。

append函数可以为切片添加元素。
s = append(s, 1 , 2, 3, 4)//为s添加四个元素。第二个参数是可变参数。
vslice = append(vslice, vslice...)//为一个切片追加另外一个切片。省略号表示取切片的每个元素。

基于数组切片创建切片:范围可以超过原有的len,但是不可以超过cap。否则会异常。
newvs := vslice[:50]
fmt.Println( cap(newvs), len (newvs))

更改数组的切片的值,会更改数组。切片类似于数组指针。

!数组切片在append后,便是脱离了原有的数组,形成了一块新的存储,更改切片值,不会再更改原有的数组内容。这是一个容易引起错误的地方。

可以使用copy函数对切片进行复制:将一个切片的内容复制到另外一个切片中。copy从第二个参数中拷贝入第一个参数中。拷贝的个数时两个切片最小元素个数。不会将剩余元素设置为空。

MAP:
定义:
var mymap map[ int]string
    变量名    key类型  value类型

var mymap map[ int]string  = map[int]string{1: "1", 2:"2" , 3:"3"}//定义并初始化

复制类似Python。可以用make创建,并制定存储能力。

删除用delete。


流程控制:

if后没有(),可以加变量定义(if i := 5; i > 2 && i <= 7{)。else必须与上一个}在一行。

switch:
条件可以是字符串等,不限定为常量或整数。
没有break。不会自动执行下一个,需要手动添加fallthrough。没有条件是,逻辑相当于 if else if ...

循环:
无限循环的写法。
for {
}

循环条件中支持多重赋值。break可以控制停止那个循环。通过标签来实现,与goto类似。

函数:
小写字母开头的包在本包可见,大写字母开头的包在外部可见。
func(arg ...int)//传递int类型的不定参数。
func(arg ...interface{})//传递不定类型的不定参数。
多返回值:定义时初始化,后面可以使用返回值变量,如果只有return,则自动返回之前的返回值变量
         
匿名函数:
由一个不带函数名的函数声明和函数体构成,可以直接赋值或执行。
闭包的用法:

func fun_test(i int)(func(a, b int)(ret bool , c int)){
      ret, e := fun1(1, 2)
      fmt.Println( "fun1 return  is :", ret, e )
      
      fun2 := func (a, b int) (ret bool, c int){
             return a < b, i
      }
      
       return fun2
}
闭包使用匿名函数来实现的。

defer,panic,recover关键字处理异常
defer关键字无论是否发生异常都会调用。
panic,recover不是特别理解,留待后面用的时候在看。

面向对象编程

类型系统:
go可以为任意类型定义方法:包括内置,当不包括指针。

type integer int:定义一个新的类型,以int为基础。

为类型定义新的方法:
func (a integer)Less(b int)bool{   //func后面的 a integer表示类型。如果方法中需要修改,则可以用a *integer
     return a < b
}

go语言一般情况是值语义,只有数组切片,map,chanel,接口是引用语义。


go提供接口查询功能。检查一个对象是否实现某一接口。也可以检查对象是否是某一类型。

接口是可以自由组合的?如何调用。

并发编程

go关键字
可以实现并发。
channel:gocoroutine之前的通信通道。是类型安全的,只能够传递一种类型。

channel的读写操作对携程来说都是阻塞的。需要再数据被写入或读取后才向下执行。类似于阻塞时的套接字。
异步处理多个套接字或者channel,可以使用select。

channel可以设置缓存,在缓冲被填满前都不好被阻塞。

可以是range从带缓冲的通道中读多个内容。

可以利用select自己增加一个通道的超时机制。

目前需要多核运行需要设置环境变量:runtime.GOMAXPROCS(4)。

出让时间片,暂停协程运行函数:Gosched。

go提供两种锁。读写锁和单一锁。

sync的once可以保证一个函数在所有的协程中(也就是全局)只被调用一次。防止多个协程对一个借口的调用。



网络编程


net的Dial函数对套接字,连接等操作进行了封装,可以选择协议,并且发起连接。除此之外还有很多分支的Dial系列接口,可以完成更丰富的操作。

go在底层封装了http的客户端和服务前端的库。

go支持rpc。net\rpc包能够支持远程调用。

gob是一个可以对数据结构进行序列化的工具。rpc内部就是使用gob。

go的net/rpc/json提供JSON-RPC。

go的encoding/json标准库,开发者可以轻松的使用go程序生成和解析json。

go编写json比较方便,可以自动将结构体的变量名编码为key,将值转化为value。(我想在c中实现的想法)

解码未知结构可以使用map。



工程管理


go提供丰富的命令行,可以完成很多工作:代码检查,格式,等。

高级话题
reflect提供放射











本文来自:CSDN博客

感谢作者:chgaowei

查看原文:go学习笔记

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。