Go
huizhang.
EasySwoole开发组成员
展开
-
协程间的信道
概念 在第一个例子中,协程是独立执行的,他们之间没有通信。他们必须通信才会变得更有用:彼此之间发送和接收信息并且协调/同步他们的工作。协程可以使用共享变量来通信,但是很不提倡这样做,因为这种方式给所有的共享内存的多线程都带来了困难。而Go有一个特殊的类型,通道(channel),像是通道(管道),可以通过它们发送类型化的数据在协程之间通信,可以避开所有内存共享导致的坑;通道的通信方式...转载 2018-05-04 23:25:44 · 489 阅读 · 0 评论 -
接口嵌套接口
一个接口可以包含一个或多个其他的接口,这相当于直接将这些内嵌接口的方法列举在外层接口中一样。比如接口 File 包含了 ReadWrite 和 Lock 的所有方法,它还额外有一个 Close() 方法。type ReadWrite interface { Read(b Buffer) bool Write(b Buffer) bool}type Lock in...转载 2018-04-06 23:22:09 · 1030 阅读 · 0 评论 -
接口是什么
简介 Go 语言不是一种 “传统” 的面向对象编程语言:它里面没有类和继承的概念。 但是 Go 语言里有非常灵活的 接口 概念,通过它可以实现很多面向对象的特性。接口提供了一种方式来 说明 对象的行为:如果谁能搞定这件事,它就可以用在这儿。 接口定义了一组方法(方法集),但是这些方法不包含(实现)代码:它们没有被实现(它们是抽象的)。接口里也不能包含变量。通过如下格式定义...转载 2018-04-06 23:15:53 · 174 阅读 · 0 评论 -
垃圾回收和 SetFinalizer
Go 开发者不需要写代码来释放程序中不再使用的变量和结构占用的内存,在 Go 运行时中有一个独立的进程,即垃圾收集器(GC),会处理这些事情,它搜索不再使用的变量然后释放它们的内存。可以通过 runtime 包访问 GC 进程。通过调用 runtime.GC() 函数可以显式的触发 GC,但这只在某些罕见的场景下才有用,比如当内存资源不足时调用 runtime.GC(),它会在此函数执行的点...转载 2018-04-06 18:12:11 · 547 阅读 · 0 评论 -
类型的 String() 方法和格式化描述符
当定义了一个有很多方法的类型时,十之八九你会使用 String() 方法来定制类型的字符串形式的输出,换句话说:一种可阅读性和打印性的输出。如果类型定义了 String() 方法,它会被用在 fmt.Printf() 中生成默认的输出:等同于使用格式化描述符 %v 产生的输出。还有 fmt.Print() 和 fmt.Println() 也会自动使用 String() 方法。代码packa...转载 2018-04-06 17:34:48 · 263 阅读 · 0 评论 -
多重继承
多重继承指的是类型获得多个父类型行为的能力,它在传统的面向对象语言中通常是不被实现的(C++ 和 Python 例外)。因为在类继承层次中,多重继承会给编译器引入额外的复杂度。但是在 Go 语言中,通过在类型中嵌入所有必要的父类型,可以很简单的实现多重继承。作为一个例子,假设有一个类型 CameraPhone,通过它可以 Call(),也可以 TakeAPicture(),但是第一个方法属于类...转载 2018-04-06 17:06:58 · 157 阅读 · 0 评论 -
如何在类型中嵌入功能
主要有两种方法来实现在类型中嵌入功能:A:聚合(或组合):包含一个所需功能类型的具名字段。B:内嵌:内嵌(匿名地)所需功能类型,像前一节 10.6.5 所演示的那样。为了使这些概念具体化,假设有一个 Customer 类型,我们想让它通过 Log 类型来包含日志功能,Log 类型只是简单地包含一个累积的消息(当然它可以是复杂的)。如果想让特定类型都具备日志功能,你可以实现一个这样的 L...转载 2018-04-06 16:25:17 · 209 阅读 · 0 评论 -
内嵌类型的方法和继承
概述 当一个匿名类型被内嵌在结构体中时,匿名类型的可见方法也同样被内嵌,这在效果上等同于外层类型 继承 了这些方法:将父类型放在子类型中来实现亚型。这个机制提供了一种简单的方式来模拟经典面向对象语言中的子类和继承相关的效果,也类似 Ruby 中的混入(mixin)。例子假定有一个 Engine 接口类型,一个 Car 结构体类型,它包含一个 Engine 类型的匿名字段:...转载 2018-04-04 23:54:12 · 422 阅读 · 1 评论 -
切片重组(reslice)
我们已经知道切片创建的时候通常比相关数组小,例如:slice1 := make([]type, start_length, capacity) 其中 start_length 作为切片初始长度而 capacity 作为相关数组的长度。 这么做的好处是我们的切片在达到容量上限后可以扩容。改变切片长度的过程称之为切片重组 reslicing,做法如下:slice1 = slic...转载 2018-03-29 00:05:40 · 1149 阅读 · 0 评论 -
数组和切片
数组 Arrays概念 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。在初始化后长度是固定的,无法修改其长度。当作为方法的入参传入时将复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度。初始化数组的初始化有多种形式[5] int {1,2,3,4,5}...转载 2018-03-28 23:45:12 · 3583 阅读 · 0 评论 -
文件拷贝
如何拷贝一个文件到另一个文件?最简单的方式就是使用 io 包:package mainimport ( "fmt" "io" "os")func main() { CopyFile("target.txt", "source.txt") fmt.Println("Copy done!")}func CopyFile(dst转载 2018-04-10 21:44:26 · 261 阅读 · 1 评论 -
文件读写
读文件在 Go 语言中,文件使用指向 os.File 类型的指针来表示的,也叫做文件句柄。我们在前面章节使用到过标准输入 os.Stdin 和标准输出 os.Stdout,他们的类型都是 *os.File。让我们来看看下面这个程序:package mainimport ( "bufio" "fmt" "io" "os")func main() { ...转载 2018-04-10 21:37:25 · 173 阅读 · 0 评论 -
Go的异常处理 defer, panic, recover
概述 Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常。在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,也就是说,遇到真正的异常的情况下(比如除数为0了)。才使...转载 2018-04-10 21:25:10 · 181 阅读 · 0 评论 -
方法和未导出字段
考虑 person2.go 中的 person 包:类型 Person 被明确的导出了,但是它的字段没有被导出。例如在 use_person2.go 中 p.firstName 就是错误的。该如何在另一个程序中修改或者只是读取一个 Person 的名字呢?这可以通过面向对象语言一个众所周知的技术来完成:提供 getter 和 setter 方法。对于 setter 方法使用 Set 前...转载 2018-04-03 14:28:45 · 264 阅读 · 0 评论 -
指针或值作为接收者
鉴于性能的原因,recv 最常见的是一个指向 receiver_type 的指针(因为我们不想要一个实例的拷贝,如果按值调用的话就会是这样),特别是在 receiver 类型是结构体时,就更是如此了。 如果想要方法改变接收者的数据,就在接收者的指针类型上定义该方法。否则,就在普通的值类型上定义方法。 下面的例子 pointer_value.go 作了说明:change()接...转载 2018-04-03 14:06:12 · 166 阅读 · 0 评论 -
函数和方法的区别
函数将变量作为参数:Function1(recv)方法在变量上被调用:recv.Method1()在接收者是指针时,方法可以改变接收者的值(或状态),这点函数也可以做到(当参数作为指针传递,即通过引用调用时,函数也可以改变参数的状态)。不要忘记 Method1 后边的括号 (),否则会引发编译器错误:method recv.Method1 is not an expression, ...转载 2018-04-03 13:32:16 · 364 阅读 · 0 评论 -
方法
方法是什么 在 Go 语言中,结构体就像是类的一种简化形式,那么面向对象程序员可能会问:类的方法在哪里呢?在 Go 中有一个概念,它和方法有着同样的名字,并且大体上意思相同:Go 方法是作用在接收者(receiver)上的一个函数,接收者是某种类型的变量。因此方法是一种特殊类型的函数。 接收者类型可以是(几乎)任何类型,不仅仅是结构体类型:任何类型都可以有方法,甚至可以是函数类型,可...转载 2018-04-03 13:29:38 · 128 阅读 · 0 评论 -
类型断言:如何检测和转换接口变量的类型
简介 一个接口类型的变量 varI 中可以包含任何类型的值,必须有一种方式来检测它的 动态 类型,即运行时在变量中存储的值的实际类型。在执行过程中动态类型可能会有所不同,但是它总是可以分配给接口变量本身的类型。通常我们可以使用 类型断言 来测试在某个时刻 varI 是否包含类型 T 的值:v := varI.(T) // unchecked type assertion...转载 2018-04-06 23:39:46 · 403 阅读 · 0 评论 -
类型判断:type-switch
接口变量的类型也可以使用一种特殊形式的 switch 来检测:type-switchswitch t := areaIntf.(type) {case *Square: fmt.Printf("Type Square %T with value %v\n", t, t)case *Circle: fmt.Printf("Type Circle %T with val...转载 2018-04-06 23:57:40 · 1010 阅读 · 0 评论 -
并发、并行和协程
知识点补充进程线程 一个应用程序是运行在机器上的一个进程;进程是一个运行在自己内存地址空间里的独立执行体。一个进程由一个或多个操作系统线程组成,这些线程其实是共享同一个内存地址空间的一起工作的执行体。几乎所有’正式’的程序都是多线程的,以便让用户或计算机不必等待,或者能够同时服务多个请求(如 Web 服务器),或增加性能和吞吐量(例如,通过对不同的数据集并行执行代码)。并发和...转载 2018-05-04 22:23:46 · 2161 阅读 · 0 评论 -
Go 中的密码学
通过网络传输的数据必须加密,以防止被 hacker(黑客)读取或篡改,并且保证发出的数据和收到的数据检验和一致。 鉴于 Go 母公司的业务,我们毫不惊讶地看到 Go 的标准库为该领域提供了超过 30 个的包: hash 包:实现了 adler32、crc32、crc64 和 fnv 校验; crypto 包:实现了其它的 hash 算法,比如 md4、md5、sha1 等。以及完...转载 2018-04-25 00:21:49 · 620 阅读 · 0 评论 -
用 Gob 传输数据
概述 Gob 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式;可以在 encoding 包中找到。这种格式的数据简称为 Gob (即 Go binary 的缩写)。类似于 Python 的 “pickle” 和 Java 的 “Serialization”。 Gob 通常用于远程方法调用(RPCs,参见 15.9 的 rpc 包)参数和结果的传输,以及应用程序和机器之间的...转载 2018-04-25 00:13:15 · 1427 阅读 · 0 评论 -
XML 数据格式
<Person> <FirstName>Laura</FirstName> <LastName>Lynn</LastName></Person> 如同 json 包一样,也有 Marshal() 和 UnMarshal() 从 XML 中编码和解码数据;但这个更通用,可以从文件中读取和写入(或者任何实...原创 2018-04-25 00:07:12 · 334 阅读 · 0 评论 -
JSON 数据格式
概述 数据结构要在网络中传输或保存到文件,就必须对其编码和解码;目前存在很多编码格式:JSON,XML,gob,Google 缓冲协议等等。Go 语言支持所有这些编码格式;在后面的章节,我们将讨论前三种格式。 结构可能包含二进制数据,如果将其作为文本打印,那么可读性是很差的。另外结构内部可能包含匿名字段,而不清楚数据的用意。 通过把数据转换成纯文本,使用命名的字段来标注,让其具...原创 2018-04-25 00:01:09 · 1978 阅读 · 0 评论 -
用 defer 关闭文件
defer 关键字对于在函数结束时关闭打开的文件非常有用,例如下面的代码片段:func data(name string) string { f, _ := os.OpenFile(name, os.O_RDONLY, 0) defer f.Close() // idiomatic Go code! contents, _ := ioutil.ReadAll(f...转载 2018-04-24 23:34:41 · 2833 阅读 · 0 评论 -
用切片读写文件
切片提供了 Go 中处理 I/O 缓冲的标准方式,下面 cat 函数的第二版中,在一个切片缓冲内使用无限 for 循环(直到文件尾部 EOF)读取文件,并写入到标准输出(os.Stdout)。package mainimport ( "flag" "fmt" "os")func cat(f *os.File) { const NBUF = 51...原创 2018-04-24 23:32:24 · 244 阅读 · 0 评论 -
用 buffer 读取文件
在下面的例子中,我们结合使用了缓冲读取文件和命令行 flag 解析这两项技术。如果不加参数,那么你输入什么屏幕就打印什么。 参数被认为是文件名,如果文件存在的话就打印文件内容到屏幕。命令行执行 cat test 测试输出。package mainimport ( "bufio" "flag" "fmt" "io" "os")f...转载 2018-04-24 00:42:19 · 2457 阅读 · 0 评论 -
标准库—命令行参数解析FLAG
以后查看不喜勿喷http://blog.studygolang.com/2013/02/%E6%A0%87%E5%87%86%E5%BA%93-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90flag/转载 2018-04-24 00:17:34 · 419 阅读 · 0 评论 -
os 包
os 包中有一个 string 类型的切片变量 os.Args,用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。来看下面的打招呼程序:// os_args.gopackage mainimport ( "fmt" "os" "strings")func main() { who := "Alice " if len(...原创 2018-04-23 23:39:20 · 373 阅读 · 0 评论 -
mac命令行编译执行运行go文件
sudo vi ~/.bash_profile添加export PATH=$PATH:/usr/local/go/binexport GOPATH=/Users/guoyuzhao/language/go 第一个为go的安装目录 第二个是运行目录原创 2018-04-23 23:33:16 · 7416 阅读 · 0 评论 -
空接口
概念 空接口或者最小接口 不包含任何方法,它对实现不做任何要求:type Any interface {} 任何其他类型都实现了空接口(它不仅仅像 Java/C# 中 Object 引用类型),any 或 Any 是空接口一个很好的别名或缩写。 空接口类似 Java/C# 中所有类的基类: Object 类,二者的目标也很相近。 可以给一个空接口类型的变量 var...转载 2018-04-07 14:05:05 · 674 阅读 · 0 评论 -
第二个例子:读和写
读和写是软件中很普遍的行为,提起它们会立即想到读写文件、缓存(比如字节或字符串切片)、标准输入输出、标准错误以及网络连接、管道等等,或者读写我们的自定义类型。为了让代码尽可能通用,Go 采取了一致的方式来读写数据。io 包提供了用于读和写的接口 io.Reader 和 io.Writer:type Reader interface { Read(p []byte) (n i...转载 2018-04-07 00:26:59 · 117 阅读 · 0 评论 -
第一个例子:使用 Sorter 接口排序
简介 一个很好的例子是来自标准库的 sort 包,要对一组数字或字符串排序,只需要实现三个方法:反映元素个数的 Len()方法、比较第 i 和 j 个元素的 Less(i, j) 方法以及交换第 i 和 j 个元素的 Swap(i, j) 方法。 排序函数的算法只会使用到这三个方法(可以使用任何排序算法来实现,此处我们使用冒泡排序):func Sort(data Sorte...转载 2018-04-07 00:24:15 · 855 阅读 · 0 评论 -
使用方法集与接口
作用于变量上的方法实际上是不区分变量到底是指针还是值的。当碰到接口类型值时,这会变得有点复杂,原因是接口变量中存储的具体值是不可寻址的,幸运的是,如果使用不当编译器会给出错误。考虑下面的程序:package mainimport ( "fmt")type List []intfunc (l List) Len() int { return len(l)}...转载 2018-04-07 00:13:07 · 206 阅读 · 0 评论 -
测试一个值是否实现了某个接口
假定 v 是一个值,然后我们想测试它是否实现了 Stringer 接口,可以这样做:type Stringer interface { String() string}if sv, ok := v.(Stringer); ok { fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv,...转载 2018-04-07 00:03:56 · 799 阅读 · 0 评论 -
匿名字段和内嵌结构体
定义结构体可以包含一个或多个 匿名(或内嵌)字段,即这些字段没有显式的名字,只有字段的类型是必须的,此时类型就是字段的名字。匿名字段本身可以是一个结构体类型,即 结构体可以包含内嵌结构体。 可以粗略地将这个和面向对象语言中的继承概念相比较,随后将会看到它被用来模拟类似继承的行为。Go 语言中的继承是通过内嵌或组合来实现的,所以可以说,在 Go 语言中,相比较于继承,组合更受青睐考虑如下的...转载 2018-04-03 10:15:52 · 1238 阅读 · 0 评论 -
带标签的结构体
结构体中的字段除了有名字和类型外,还可以有一个可选的标签(tag):它是一个附属于字段的字符串,可以是文档或其他的重要标记。标签的内容不可以在一般的编程中使用,只有包 reflect 能获取它。我们将在下一章(第 11.10 节)中深入的探讨 reflect包,它可以在运行时自省类型、属性和方法,比如:在一个变量上调用 reflect.TypeOf() 可以获取变量的正确类型,如果变量是一个...转载 2018-04-03 10:06:27 · 457 阅读 · 0 评论 -
反射包
方法和类型的反射 我们看到可以通过反射来分析一个结构体。本节我们进一步探讨强大的反射功能。反射是用程序检查其所拥有的结构,尤其是类型的一种能力;这是元编程的一种形式。反射可以在运行时检查类型和变量,例如它的大小、方法和 动态 的调用这些方法。这对于没有源代码的包尤其有用。这是一个强大的工具,除非真得有必要,否则应当避免使用或小心使用。 变量的最基本信息就是类型和值:反射包的 Typ...转载 2018-04-07 14:26:42 · 157 阅读 · 0 评论 -
将 map 的键值对调
这里对调是指调换 key 和 value。如果 map 的值类型可以作为 key 且所有的 value 是唯一的,那么通过下面的方法可以简单的做到键值对调。package mainimport ( "fmt")var ( barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23, ...转载 2018-03-30 10:38:58 · 2470 阅读 · 0 评论 -
map 的排序
map 默认是无序的,不管是按照 key 还是按照 value 默认都不排序 如果你想为 map 排序,需要将 key(或者 value)拷贝到一个切片,再对切片排序,然后可以使用切片的 for-range 方法打印出所有的 key 和 value。// the telephone alphabet:package mainimport ( "fmt" "sort"...转载 2018-03-30 10:34:43 · 213 阅读 · 0 评论