Golang学习笔记

来源:互联网 发布:linux下解压tar.bz2 编辑:程序博客网 时间:2024/05/15 23:45
如果一个method的receiver是*T,你可以在一个T类型的实例变量V上面调用这个method,而不需要&V去调用这个method(即不需要(&V).method())。如果一个method的receiver是T,你可以在一个*T类型的变量P上调用这个method,而不需要*P去调用这个method。

interface类型

interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。

任意的类型都实现了空interface(interface{}),也就是包含0个method的interface。

如果定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。

interface就是一组抽象方法的集合,它必须由其他非interface类型实现,而不能自我实现。

空interface(interface{})不包含任何的method,正因为如此,所有的类型都实现了空interface。空interface对于描述起不到任何的作用(因为它不包含任何的method),但是空interface在需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。

一个函数使用interface{}作为参数,那么它可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值。

type Stringer interface {    String() string}

如果需要某个类型能被fmt包以特殊的格式输出,你就必须实现Stringer接口。

实现了error接口的对象(即实现了Error() string方法的对象),使用fmt输出时,会调用Error()方法,因此不必再定义String()方法了。

反射

Go语言实现了反射,所谓反射就是能检查程序在运行时的状态。

使用reflect一般分成三步:要去反射是一个类型的值(这些值都实现了空interface),首先需要把它转化成reflect对象(reflect.Type或者reflect.Value,根据不同的情况调用不同的函数)。

并发

goroutine是Go并行设计的核心。goroutine说到底其实就是线程,但是它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。

goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。那么goroutine之间如何进行数据的通信呢,Go提供了一个很好的通信机制channel。channel可以与Unix shell 中的双向管道做类比:可以通过它发送或者接收值。这些值只能是特定的类型:channel类型。定义一个channel时,也需要定义发送到channel的值的类型。注意,必须使用make 创建channel:

ci := make(chan int)cs := make(chan string)cf := make(chan interface{})

channel通过操作符<-来接收和发送数据。

ch <- value // 将value发送到channelvalue := <- ch // 从ch中接收数据,并赋值给value

默认的channel是非缓存类型的、阻塞的。

当存在多个channel时,Go里面提供了一个关键字select,通过select可以监听channel上的数据流动。select默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,当多个channel都准备好的时候,select是随机的选择一个执行的。在select里面还有default语法,select其实就是类似switch的功能,default就是当监听的channel都没有准备好的时候,默认执行的(select不再阻塞等待channel)。

0 0