【Go】杂七杂八GoLang

assert

  • Every assertion function also takes an optional string message as the final argument, allowing custom error messages to be appended to the message the assertion method outputs.

  • func TestSomething(t *testing.T) {
      var a string = "Hello"
      var b string = "Hello"
      assert.Equal(t, a, b, "The two words should be the same.")
    }
    // assert many times
    func TestSomething(t *testing.T) {
      assert := assert.New(t)
    
      var a string = "Hello"
      var b string = "Hello"
    
      assert.Equal(a, b, "The two words should be the same.")
    }
    

validator

  • required :必填
  • email:验证字符串是email格式;例:“email”
  • url:这将验证字符串值包含有效的网址;例:“url”
  • max:字符串最大长度;例:“max=20”
  • min:字符串最小长度;例:“min=6”
  • excludesall:不能包含特殊字符;例:“excludesall=0x2C”//注意这里用十六进制表示。
  • len:字符长度必须等于n,或者数组、切片、map的len值为n,即包含的项目数;例:“len=6”
  • eq:数字等于n,或者或者数组、切片、map的len值为n,即包含的项目数;例:“eq=6”
  • ne:数字不等于n,或者或者数组、切片、map的len值不等于为n,即包含的项目数不为n,其和eq相反;例:“ne=6”
  • gt:数字大于n,或者或者数组、切片、map的len值大于n,即包含的项目数大于n;例:“gt=6”
  • gte:数字大于或等于n,或者或者数组、切片、map的len值大于或等于n,即包含的项目数大于或等于n;例:“gte=6”
  • lt:数字小于n,或者或者数组、切片、map的len值小于n,即包含的项目数小于n;例:“lt=6”
  • lte:数字小于或等于n,或者或者数组、切片、map的len值小于或等于n,即包含的项目数小于或等于n;例:“lte=6”

函数

  • variadic:有时候参数过多,或者想要让函数处理任意多个的参数,可以在函数定义语句的参数部分使用ARGS...TYPE的方式。这时会将...代表的参数全部保存到一个名为ARGS的slice中,注意这些参数的数据类型都是TYPE。
  • 接收器和方法:func和方法名之间有一个参数,这个参数为方法的receiver,于是定义的这个方法和接收者绑定在了一起。类似于Java中的类内的成员函数。
  • 返回值变量,要不都有变量名,要不就一个变量名对应一个类型。

goroutine

  • goroutine是Go中轻量级线程实现,由Go运行时(runtime)管理。
  • 关键字 go 创建一个goroutine。
  • 所有的goroutine在main()函数结束时会一同结束。

闭包

  • Go中闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量。
  • 闭包会使得函数中的变量都被保存在内存中,内存消耗很大。

Context

  • 用于设置截止日期、同步信号,传递请求相关值的结构体。

  • // 需要实现这4个方法
    type Context interface {
    	Deadline() (deadline time.Time, ok bool)
    	Done() <-chan struct{}
    	Err() error
    	Value(key interface{}) interface{}
    }
    

reflect

  • reflect.TypeOf():返回一个表示着唯一接口参数值的动态类型的reflect.Type值
  • reflect.Type类型对象有成员函数
    • Name(): 类型名
    • Kind():种类

interface{ }类型

  • interface{}类型,空接口,是没有方法的接口,所有类型都实现了空接口。

废弃方法api

  • 在方法上加上注释Deprecated

cap

  • arry:返回数组的元素个数
  • slice:返回slice的最大容量
  • channel:返回channel的buffer容量

语法

  • 取反:用^或者!,go不支持~符号。
  • import:import后面跟的是包路径,而不是包名。
    • 同个目录下可以有多个.go文件,但是只能有一个包。
    • 使用第三方库时,先将源码编译.a文件放到临时目录下,然后去链接这个.a文件,而不是go install安装的那个.a文件;
    • 使用标准库时,直接链接.a文件,即使修改了源码,也不会从新编译源码;
    • 不管使用的是标准库还是第三方库,源码都是必须存在的,即使使用的是.a文件。
  • 常量:go语言常量要是编译时就能确定的数据
    • errors.New("xxx") 要等到运行时才能确定,所以它不能是const。
    • 存储在常量中的数据类型只可以是布尔型、数字型(int, float, complex)和string。
  • 循环语句
    • switch
      • 声明语句和表达式语句都是可选的。(可以不设定swicth后的条件表达式,和if...else同个效果)
      • 不需要break手动退出case。
      • 条件表达式限制为常量or整数。
  • 字符串:字符串是不可变的,是不定长字节,不能对字符串中某个字符单独赋值,不支持下标操作。
  • 指针:不支持指针运算。
  • 平行赋值:等号左边和右边含有多个表达式。
  • 高级break:可以选择中断哪个循环。
  • main
    • main函数不能带参数
    • main函数不能定义返回值
    • main函数所在的包必须是main包
    • main函数中可以使用flag包来获取和解析命令行参数

struct、interface

  • go里没有类这个概念
  • interface中只能定义函数,不能定义变量。
  • struct里只能定义变量。
  • struct对interface的实现是隐式的,只要实现了interface里的函数,则相当于实现了interface,效果有点像成员方法。

go框架

GoMock

  • interface可以通过GoMock框架打桩。

redigo

redis.Conn链接对象相关方法

  • conn.Do() :Do发送一条命令到redis服务器端执行并返回结果
  • conn.Send(): Send发送命令到缓存
  • conn.Flush(): Flush发送命令到服务端执行
  • conn.Receive(): Receive方法获取命令执行结果
  • conn.Close(): 关闭链接

Pool连接池获取conn对象

  • pool封装dial实现连接池。

  • conn := pool.Get() //get方法获取conn链接对象
    
  • redis.Dial():获取conn

DialOption生效

  1. 先在DialURL中参数options中设置DialClientname。

  2. DialClientName返回了一个DialOption,这个DialOption设置了clientname。

    • DialOption这个struct包了一个func,在func里面对参数do进行设置。

    func DialClientName(name string) DialOption {
    	return DialOption{func(do *dialOptions) {
    		do.clientName = name
    	}}
    }
    
  3. DialURL中设置passwd, address等,然后调用Dial

  4. Dial调用DialContext

    1. Dial只是调用了DialContext,传入context.Background作为Context。

    func Dial(network, address string, options ...DialOption) (Conn, error) {
    	return DialContext(context.Background(), network, address, options...)
    }
    
  5. DialContext

    1. 设置dialOptions类型do中Timeout、Keepalive、tlsHandshakeTiemout等参数。
    2. 调用options中的f func,设置do的clientname字段。
    3. 通过do的dialContext获得netConn,获得&conn的c。
    4. do.clientname!=""才调用c.do进行设置CLIENTNAME。
  • 当clientname为空字符串时,其实是不会进行设置clientname的。

Go程序加载流程

  • img
  • 初始化流程,执行main.main()之前,Go引导程序会先对整个程序的包进行初始化。
    1. 包初始化从main()引用的包开始,逐级查找,最终生成一个包引用的有向无环图。
    2. 先初始化常量 const...
    3. 然后初始化全局变量 var...
    4. 执行包的init()

go内存管理机制

golang中不存在野指针

  • go语言的自动内存管理机制使得只要还有一个指针引用一个变量,那这个变量就会在内存中得以保留。
  • go语言中变量是分配在栈中还是在堆中也是不能确定的,栈中的变量可能会逃逸到堆,堆中的变量也可能因为编译优化而在栈中分配,这都是由go语言管理的。

内存泄漏

  • 在Go语言里,我们检测内存泄漏主要依靠的是go里面的pprof包
  • 除此之外,我们还可以使用浏览器来查看系统的实时内存信息(包括CPU、goroutine等的信息)。

序列化和反序列化

  • 序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中;
  • 反序列化即逆过程,由字节流还原成对象。
  • 序列化通常讲类型结构传入标准库or第三方包。
  • 结构体在序列化时非导出变量(以小写字母开头的变量名)不会被encode,因此在decode时这些非导出变量的值为其类型的零值。
原文地址:https://www.cnblogs.com/xuwanwei/p/15123276.html