-
go语言是静态型和编译型的语言,使得其运行效率很高查看全部
-
与针对字典值的索引表达式一样,针对通道值得接受操作也可以有第二个结果值。如下: value, ok := <- ch1 这样做的目的是为了消除与零值有关的歧义。这里的变量ok的值同样是bool类型。它代表了通道值得状态,true代表通道值有效,而false代表通道值已无效(或称已关闭)。更深层次的原因是,如果在接收操作进行之前或者过程中通道值被关闭了,则接收操作会立即结束并返回一个该通道值得元素类型的零值。按照上面的第一种写法,我们无从判断接收零值的原因。 关闭通道值,调用内建函数close来达到目的 :close(ch1) 对通道之的重复关闭会引发运行时恐慌。会使程序崩溃。一定要避免这种情况。另外,在通道值有效的前提下,针对它的发送操作会在通道值已满(其中缓存的数据的个数已等于它的长度)时被阻塞。想一个已被关闭的通道值发送数据会引发运行时恐慌。另一方面,针对有效通道值的接收操作会在它已空(其中美欧缓存任何数据)时被阻塞。 与切片和字典类型相同,通道类型属于引用类型。它的零值即为nil。查看全部
-
通道值得长度应该被成为其缓存的尺寸。它代表着通道值中可以咱村的数据的个数。暂存在通道值中的数据是先进先出的,即:越早被放入(或称发送)到通道值得数据会越先被取出(或接收)。 声明一个通道类型的变量,并赋值: ch1 := make(chan string, 5) 我们可以使用接收操作符<-向通道值发送数据。也可以使用它从通道值接收数据。如,如果我们要向通道ch1发送字符串"value1", 那么应该这么做: ch1 <- "value1" 另一方面,我们若想从ch1那里接收字符串,需要:<- ch1 这时,我们可以直接把接收到的字符串赋值给一个变量,如: value := <- ch1查看全部
-
通道(Channel)是Go语言中一种非常独特的数据结构。它可用于在不同Goroutine之间传递类型化的数据,并且是并发安全的。之前的数据类型都不是并发安全的。 Goroutine(Go程序)可被看做是承载可被兵法执行的代码块的载体。它们由Go语言的运行时系统调度,并依托操作系统线程(内核线程)来并发的执行其中的代码块。 表示方法: chan T 解释:左边是代表通道类型的关键chan,右侧是一个可变部分,即代表该通道类型允许传递的数据的类型(或称通道的元素类型)。之间需要以空格分隔。 因为我们无法表示一个通道类型的值,因此,无法用字面量来为通道类型的变量赋值。只能通过调用内建函数make达到目的。make函数可接受两个参数。第一个参数是代表了将被初始化的值得类型的字面量(比如chan int),而第二个参数则是值得长度。例如,若我们想要初始化一个长度为5且元素类型为int的通道值,需要这么来写: make(chan int, 5) 实际上make函数也可以被用来初始化切片类型或字典类型的值。查看全部
-
解压:$ sudo tar -zxf go1.9.1.linux-amd64.tar.gz -C /usr/local 测试:$ cd /usr/local/go $ bin/go version 设置:$ vim /etc/profile # 插入在最后一行 export GOROOT=/usr/local/go export GOPATH=~/golib:~/goproject export GOBIN=~/gobin export PATH=$PATH:$GOROOT/bin:$GOBIN $ source /etc/profile 完成:$ go version查看全部
-
errors.New是一个很常用的函数。在Go语言标准库的代码包中有很多由此函数创建出来的错误值,比如os.ErrPermission、io.EOF等变量的值。我们可以很方便地用操作符==来判断一个error类型的值与这些变量的值是否相等,从而来确定错误的具体类别。就拿io.EOF来说,它代表了一个信号。该信号用于通知数据读取方已无更多数据可读。我们在得到这样一个错误的时候不应该把它看成一个真正的错误,而应该只去结束相应的读取操作。查看全部
-
项目源代码获取查看全部
-
1.defer语句仅能被放置在函数或方法中。它由关键字defer和一个调用表达式组成。 注意,这里的调用表达式所表示的既不能是对Go语言内建函数的调用也不能是对Go语言标准库代码包unsafe中的那些函数的调用。 2.当一个函数中存在多个defer语句时,它们携带的表达式语句的执行顺序一定是它们的出现顺序的倒序。 3.defer携带的表达式语句代表的是对某个函数或方法的调用。这个调用可能会有参数传入,比如:fmt.Print(i + 1)。 如果代表传入参数的是一个表达式,那么在defer语句被执行的时候该表达式就会被求值了。 注意,这与被携带的表达式语句的执行时机是不同的。 4. 如果defer携带的表达式语句代表的是对匿名函数的调用,那么我们就一定要非常警惕。查看全部
-
select语句属于条件分支流程控制方法,不过它只能用于通道。它可以包含若干条case语句,并根据条件选择其中的一个执行。进一步说,select语句中的case关键字只能后跟用于通道的发送操作的表达式以及接收操作的表达式或语句。示例如下: ch1 := make(chan int, 1) ch2 := make(chan int, 1) // 省略若干条语句 select { case e1 := <-ch1: fmt.Printf("1th case is selected. e1=%v.\n", e1) case e2 := <-ch2: fmt.Printf("2th case is selected. e2=%v.\n", e2) default: fmt.Println("No data!") } 如果该select语句被执行时通道ch1和ch2中都没有任何数据,那么肯定只有default case会被执行。但是,只要有一个通道在当时有数据就不会轮到default case执行了。显然,对于包含通道接收操作的case来讲,其执行条件就是通道中存在数据(或者说通道未空)。如果在当时有数据的通道多于一个,那么Go语言会通过一种伪随机的算法来决定哪一个case将被执行。 另一方面,对于包含通道发送操作的case来讲,其执行条件就是通道中至少还能缓冲一个数据(或者说通道未满)。类似的,当有多个case中的通道未满时,它们会被随机选择。 如果一条select语句中不存在default case, 并且在被执行时其中的所有case都不满足执行条件,那么它的执行将会被阻塞!当前流程的进行也会因此而停滞。直到其中一个case满足了执行条件,执行才会继续。我们一直在说case执行条件的满足与否取决于其操作的通道在当时的状态。这里特别强调一点,即:未被初始化的通道会使操作它的case永远满足不了执行条件。对于针对它的发送操作和接收操作来说都是如此。 最后提一句,break语句也可以被包含在select语句中的case语句中。它的作用是立即结束当前的select语句的执行,不论其所属的case语句中是否还有未被执行的语句。查看全部
-
1.只要在panic或其调用栈之前加上defer ... recover语句就可以了。 2.recover语句所在函数与panic所在函数与两个函数之间的函数都不再往下运行。recover语句所在函数上的函数继续往下运行。查看全部
-
defer表达式在其外函数运行结束前的最后一刻执行。查看全部
-
defer表达式的参数表达式不推迟执行。查看全部
-
for语句代表着循环。一条语句通常由关键字for、初始化子句、条件表达式、后置子句和以花括号包裹的代码块组成。其中,初始化子句、条件表达式和后置子句之间需用分号分隔。 我们可以省略掉初始化子句、条件表达式、后置子句中的任何一个或多个,不过起到分隔作用的分号一般需要被保留下来,除非在仅有条件表达式或三者全被省略时分号才可以被一同省略。 for语句还有另外一种编写方式,那就是用range子句替换掉for子句。range子句包含一个或两个迭代变量(用于与迭代出的值绑定)、特殊标记:=或=、关键字range以及range表达式。其中,range表达式的结果值的类型应该是能够被迭代的,包括:字符串类型、数组类型、数组的指针类型、切片类型、字典类型和通道类型。 对于字符串类型的被迭代值来说,for语句每次会迭代出两个值。第一个值代表第二个值在字符串中的索引,而第二个值则代表该字符串中的某一个字符。迭代是以索引递增的顺序进行的。 字符串的底层是以字节数组的形式存储的。而在Go语言中,字符串到字节数组的转换是通过对其中的每个字符进行UTF-8编码来完成的。注意,一个中文字符在经过UTF-8编码之后会表现为三个字节。 对于数组值、数组的指针值和切片之来说,range子句每次也会迭代出两个值。其中,第一个值会是第二个值在被迭代值中的索引,而第二个值则是被迭代值中的某一个元素。同样的,迭代是以索引递增的顺序进行的。 对于字典值来说,range子句每次仍然会迭代出两个值。显然,第一个值是字典中的某一个键,而第二个值则是该键对应的那个值。注意,对字典值上的迭代,Go语言是不保证其顺序的。 携带range子句的for语句还可以应用于一个通道值之上。其作用是不断地从该通道值中接收数据,不过每次只会接收一个值。注意,如果通道值中没有数据,那么for语句的执行会处于阻塞状态。无论怎样,这样的循环会一直进行下去。直至该通道值被关闭,for语句的执行才会结束。 break语句和continue语句都可以被放置在for语句的代码块中。前者被执行时会使其所属的for语句的执行立即结束,而后者被执行时会使当次迭代被中止(当次迭代的后续语句会被忽略)而直接进入到下一次迭代。查看全部
-
'a'是int32类型,不是string。查看全部
-
switch语句提供了一个多分支条件执行的方法。在这里用一个专有名词来代表分支——case。每一个case可以携带一个表达式或一个类型说明符。前者又可被简称为case表达式。因此,Go语言的switch语句又分为表达式switch语句和类型switch语句。 在表达式switch语句中,每个case会携带一个表达式。与if语句中的条件表达式不同,这里的case表达式的结果类型并不一定是bool。不过,它们的结果类型需要与switch表达式的结果类型一致。所谓switch表达式是指switch语句中要被判定的那个表达式。switch语句会依据该表达式的结果与各个case表达式的结果是否相同来决定执行哪个分支。 switch表达式必须紧随switch关键字出现。在后面的花括号中,一个关键字case、case表达式、冒号以及后跟的若干条语句组成为一条case语句。在switch语句中可以有若干条case语句。Go语言会依照从上至下的顺序对每一条case语句中case表达式进行求值。只要被发现其表达式与switch表达式的结果相同,该case语句就会被选中。它包含的那些语句就会被执行。而其余的case语句则会被忽略。 switch语句中还可以存在一个特殊的case——default case。顾名思义,当没有一个常规的case被选中的时候,default case就会被选中。上面示例中就存在一个default case。它由关键字default、冒号和后跟的一条语句组成。实际上,default case不一定被追加在最后。它可以是第一个case,或者出现在任意顺位上。 类型switch语句。它与一般形式有两点差别。第一点,紧随case关键字的不是表达式,而是类型说明符。类型说明符由若干个类型字面量组成,且多个类型字面量之间由英文逗号分隔。第二点,它的switch表达式是非常特殊的。这种特殊的表达式也起到了类型断言的作用,但其表现形式很特殊,如:v.(type),其中v必须代表一个接口类型的值。注意,该类表达式只能出现在类型switch语句中,且只能充当switch表达式。 fallthrough是一个关键字,又可以代表一条语句。fallthrough语句可被包含在表达式switch语句中的case语句中。它的作用是使控制权流转到下一个case。查看全部
举报
0/150
提交
取消