golang中chan实例

package main

import "fmt"

func main() {
 data := make(chan int) // 数据交换队列
 exit := make(chan bool) // 退出通知

go func() {
 for d := range data { // 从队列迭代接收数据,直到 close 。
   fmt.Println(d)
 }

 fmt.Println("recv over.")
 exit <- true // 发出退出通知。
}()

data <- 1 // 发送数据。
data <- 2
data <- 3

close(data) // 关闭队列。

fmt.Println("send over.")

<-exit // 等待退出通知。
}

输出结果:

1
2
3
send over.
recv over.

而如果将上面与 exit chan有关的三行删除掉,则结果为:

1
2
3
send over.

缺少了“recv over."一行,为什么?

大家可以  time.Sleep(time.Second * 2) 来自己分析一下

golang中chan的理解与使用教程

对于 chan 介绍见:https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/02.7.md

这里我们主要通过实例来介绍对chan的理解及用法.

无Buffer的Channels

实例1:

func main() {
ci := make(chan int)

ci < - 4

value := <-ci
fmt.Println(value)
}

执行结果错误为:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:

从上面“fatal error: all goroutines are asleep - deadlock!” 这句我们可以看出是groutings 阻塞了,这里为写阻塞,从“goroutine 1 [chan send]”可以看出来。 Continue reading

golang中flag包的用法

golang中flag包主要用来CLI下,获取命令参数,示例如下mysql.go:

package main

import (
"flag"
"fmt"
)

func main() {
host := flag.String("h", "localhost", "请指定一个主机")
user := flag.String("u", "root", "请指定数据库用户")
port := flag.Int("P", 3306, "Port number to use for commection or 0 for default to, in port 3306")

//var name string
//flag.StringVar(&name, "u", "root", "请指定用户名") 

flag.Parse() //参数解析

fmt.Println("主机地址:", *host)
fmt.Println("用户名:", *user)
fmt.Println("端口:", *port)
}

像flag.Int、flag.Bool、flag.String这样的函数格式都是一样的,第一个参数表示参数名称,第二个参数表示默认值,第三个参数表示使用说明和描述。flag.StringVar这样的函数第一个参数换成了变量地址,后面的参数和flag.String是一样的。

使用flag来操作命令行参数,支持的格式如下:

-id=1 go run mysql.go -h="127.0.0.1" -u="sxf" -P=3307 
--id=1: go run mysql.go --h="127.0.0.1" --u="sxf" --P=3307 
-id 1:  go run mysql.go -h "127.0.0.1" -u "sxf" 
--id 1:  go run mysql.go --h "127.0.0.1" --u "sxf" --P 3307

还是非常方便的。

这里不指定参数的情况,会使用默认值:

go run mysql.go

 

Golang语言的GOPATH与工作目录详解

这篇文章主要介绍了Go语言的GOPATH与工作目录详解,本文详细讲解了GOPATH设置、应用目录结构、编译应用等内容,需要的朋友可以参考下

GOPATH设置

go 命令依赖一个重要的环境变量:$GOPATH

(注:这个不是Go安装目录。下面以笔者的工作目录为说明,请替换自己机器上的工作目录。)

在类似 Unix 环境大概这样设置:

export GOPATH=/home/apple/mygo

为了方便,应该把新建以上文件夹,并且把以上一行加入到 .bashrc 或者 .zshrc 或者自己的 sh 的配置文件中。

Windows 设置如下,新建一个环境变量名称叫做GOPATH:

GOPATH=c:\mygo

GOPATH允许多个目录,当有多个目录时,请注意分隔符,多个目录的时候Windows是分号,Linux系统是冒号,当有多个GOPATH时,默认会将go get的内容放在第一个目录下

以上 $GOPATH 目录约定有三个子目录:

1.src 存放源代码(比如:.go .c .h .s等)
2.pkg 编译后生成的文件(比如:.a)
3.bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用${GOPATH//://bin:}/bin添加所有的bin目录)

以后我所有的例子都是以mygo作为我的gopath目录
Continue reading

golang中for循环方法的差异

用for循环遍历字符串时,也有 byte 和 rune 两种方式.第一种试为byte,第二种rune。

golang中string rune byte 三者的关系https://blog.haohtml.com/archives/17646

package main
import (
	"fmt"
)

func main() {
	s := "abc汉字"
 
	for i := 0; i < len(s); i++ {
	fmt.Printf("%c,", s[i])
	}
	 
	fmt.Println()
	 
	for _, r := range s {
		fmt.Printf("%c\n", r)
	}

}

输出结果:

a,b,c,d,e,f,d,ä,¸,­,
a,b,c,æ,±,‰,å,­,—,
a
b
c
汉
字

Golang import使用说明

我们在写Go代码的时候经常用到import这个命令用来导入包文件,而我们经常看到的方式参考如下:

import(
"fmt"
)

然后我们代码里面可以通过如下的方式调用

fmt.Println("hello world")

上面这个fmt是Go语言的标准库,他其实是去goroot下去加载该模块,当然Go的import还支持如下两种方式来加载自己写的模块:

1.相对路径

import “./model” //当前文件同一目录的model目录,但是不建议这种方式来import

2.绝对路径

import “shorturl/model” //加载gopath/src/shorturl/model模块

上面展示了一些import常用的几种方式,但是还有一些特殊的import,让很多新手很费解,下面我们来一一讲解一下到底是怎么一回事 Continue reading