开始第一个程序

打开Shell窗口或Windows下的命令行窗口,切换到$GOPATH\src文件夹。

1
2
3
4
cd $GOPATH
mkdir -p github.com/devuser/golang-notes/golang-step-1/helloworld
touch github.com/devuser/golang-notes/golang-step-1/helloworld/main.go
cd github.com/devuser/golang-notes/golang-step-1/helloworld

如果在Windows下需要将$GOPATH修改成%GOPATH%。 上述mkdir -p也要查询如何之后做调整。 touch用来创建一个空文件,如果在Windows下可以输入nodepad打开一个空文件。

复制如下代码到main.go

1
2
3
4
5
6
7
8
9
10
package main

import (
"fmt"
)

func main() {

fmt.Println("Hello world!")
}

保存。

使用build命令

回到Shell窗口或Windows下的命令行窗口。 输入命令

1
go run main.go

看到输出结果

1
Hello world!

如果要编译成可执行文件

1
2
3
go build -o helloworld main.go
chmod +x helloworld
./helloworld

或Windows下

1
2
go build -o helloworld.exe main.go
.\helloworld.exe

使用上述命令可以编译产生可以执行文件。

当然您可以把可执行文件保存在$GOPATH/bin目录

1
2
3
go build -o $GOPATH/bin/helloworld main.go
chmod +x $GOPATH/bin/helloworld
$GOPATH/bin/helloworld

建议

建议在环境变量中修改,把$GOPATH/bin添加到$PATH

1
$PATH=$GOPATH/bin:$PATH

go run 使用

  • go run [fileName].go 用于执行go的源代码 如go run helloworld.go
  • go run [fileName].go -argK=argV 带参数[argK]执行go的源代码

笔者常用的命令方式

1
go run XXX.go -ini=XXX.json -log=XXX.log

go run 常用标记

  • -a:强制编译相关代码,无论是否编译过
  • -v:列出被编译的代码包的名称
  • -a -v:列出所有被编译的代码包的名称
  • -p n:并行编译,其中n为并行的数量 如-p 2
  • -n:打印编译过程中所需运行的命令,但并不执行这些命令
  • -x:打印编译过程中所需运行的命令,并执行这些命令
  • -work:显示编译时创建的临时工作目录的路径,并且不删除这个临时工作目录

使用方式:如 go run -v [fileName].go

@TODO: 暂时没找到指定临时工作目录的方法。

Makefile示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#@Author: devuser@gmail.com
#@date: 2018-09-14
#@comment:
# Go parameters
BINARY_NAME=case_makefile
BINARY_LINUX=$(BINARY_NAME)_linux
BINARY_386=$(BINARY_NAME)_386_win32.exe
BINARY_AMD64=$(BINARY_NAME)_amd64_win64.exe

GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOCMD=go
GOFMT ?= gofmt "-s"
GOGET=$(GVT) fetch
GOTEST=$(GOCMD) test
GVT=gvt
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
# GOPATH=/data/boyosoft/goBillProcess
all: test build
build:
$(GOBUILD) -o $(BINARY_NAME) -v
test:
$(GOTEST) -v ./...
clean:
$(GOCLEAN)
rm -f $(BINARY_NAME)
rm -f $(BINARY_linux)
rm -f "case_makefile.log"
rm -rf "test.db"
run: clean
# $(GOBUILD) -o $(BINARY_NAME) -v ./...
# ./$(BINARY_NAME)
$(GOCMD) run main.go
deps:
cd $(GOPATH)/src
# $(GOGET) github.com/markbates/goth
# $(GOGET) github.com/markbates/pop
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
gvt fetch github.com/golang/lint/golint; \
fi
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
gvt fetch github.com/client9/misspell/cmd/misspell; \
fi
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
gvt fetch github.com/kardianos/govendor; \
fi
@hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
gvt fetch github.com/campoy/embedmd; \
fi
cd $(GOPATH)/src/github.com/boyosoft/case_makefile

.PHONY: fmt
fmt:
$(GOFMT) -w $(GOFILES)

.PHONY: fmt-check
fmt-check:
# get all go files and run go fmt on them
@diff=$$($(GOFMT) -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi;

vet:
go vet $(VETPACKAGES)

# Cross compilation
build-linux:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_LINUX) -v
build-win32:
CGO_ENABLED=0 GOOS=windows GOARCH=386 $(GOBUILD) -o $(BINARY_386) -v
build-win64:
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BINARY_AMD64) -v

# docker-build:
# echo "build the $(BINARY_LINUX) in docker"
# docker run --rm -it -v "$(GOPATH)":/data/boyosoft/goBillProcess -w /data/boyosoft/goBillProcess/src/github.com/boyosoft/case_makefile devuser/gopher go build -o "$(BINARY_LINUX)" -v

Mac下编译提交Shell脚本示例

Mac下编译提交Shell脚本示例

编译、版本管理走过如下几个步骤

  1. 获得时间戳

  2. 切换到源代码目录

  3. 清理现场

  4. 运行,输出新的配置文件(示例中采用json作为配置文件)

  5. 编译,指定目标文件

  6. 提交源代码到git服务器,并设置备注

1
2
3
4
5
6
7
8
9
10
11
12

#!/bin/sh
export TS=$(date +%Y%m%d%H%M%S)
cd $GOPATH/src
rm -rf ../pkg
go clean
rm -rf YOUR_PROGRAMNAME.json
go run YOUR_PROGRAMNAME.go
go build -o ~/tmp/gittest/YOUR_PROGRAMNAME YOUR_PROGRAMNAME.go
cp YOUR_PROGRAMNAME.json ~/tmp/gittest
git commit -a -m "update $TS"
git push

Mac下Shell脚本示例2

如下脚本示例包含如下内容,鼓励读者使用Ant管理测试案例。

  1. 使用Ant管理测试案例

  2. 在运行golang程序前,调用Ant准备测试环境,比如运行数据库脚本,复制测试数据文件到特定文件夹

  3. 运行go run,并指定配置文件

鉴于目前gopher在开发、测试、生产环境下的OS可能不同,鼓励保存不同的配置文件, 在go run时选择特定的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13

#!/bin/bash
echo "hello the world"
export TARGETNAME="PTS.copyCurrentMonth"
echo "call $TARGETNAME begin"
ant -f buildmac.xml $TARGETNAME

echo "call $TARGETNAME over"
cd $GOPATH/src
echo "call YOUR_PROGRAMNAME.go begin"
go run YOUR_PROGRAMNAME.go -ini=YOUR_PROGRAMNAMEmac.json

echo "call YOUR_PROGRAMNAME.go over"

Mac下Shell脚本示例3

1
2
3
4
5
6
7
8

#!/bin/sh
cd $GOPATH/src
rm -rf ../pkg
go clean
rm -rf wepiaomock.json
go run wepiaomock.go
go run wepiaomock.go

开始第一个程序

打开Shell窗口或Windows下的命令行窗口,切换到$GOPATH\src文件夹。

1
2
3
4
cd $GOPATH
mkdir -p github.com/devuser/golang-notes/golang-step-1/helloworld
touch github.com/devuser/golang-notes/golang-step-1/helloworld/main.go
cd github.com/devuser/golang-notes/golang-step-1/helloworld

如果在Windows下需要将$GOPATH修改成%GOPATH%。 上述mkdir -p也要查询如何之后做调整。 touch用来创建一个空文件,如果在Windows下可以输入nodepad打开一个空文件。

复制如下代码到main.go

1
2
3
4
5
6
7
8
9
10
package main

import (
"fmt"
)

func main() {

fmt.Println("Hello world!")
}

保存。

使用build命令

回到Shell窗口或Windows下的命令行窗口。 输入命令

1
go run main.go

看到输出结果

1
Hello world!

如果要编译成可执行文件

1
2
3
go build -o helloworld main.go
chmod +x helloworld
./helloworld

或Windows下

1
2
go build -o helloworld.exe main.go
.\helloworld.exe

使用上述命令可以编译产生可以执行文件。

当然您可以把可执行文件保存在$GOPATH/bin目录

1
2
3
go build -o $GOPATH/bin/helloworld main.go
chmod +x $GOPATH/bin/helloworld
$GOPATH/bin/helloworld

建议

建议在环境变量中修改,把$GOPATH/bin添加到$PATH

1
$PATH=$GOPATH/bin:$PATH

go run 使用

  • go run [fileName].go 用于执行go的源代码 如go run helloworld.go
  • go run [fileName].go -argK=argV 带参数[argK]执行go的源代码

笔者常用的命令方式

1
go run XXX.go -ini=XXX.json -log=XXX.log

go run 常用标记

  • -a:强制编译相关代码,无论是否编译过
  • -v:列出被编译的代码包的名称
  • -a -v:列出所有被编译的代码包的名称
  • -p n:并行编译,其中n为并行的数量 如-p 2
  • -n:打印编译过程中所需运行的命令,但并不执行这些命令
  • -x:打印编译过程中所需运行的命令,并执行这些命令
  • -work:显示编译时创建的临时工作目录的路径,并且不删除这个临时工作目录

使用方式:如 go run -v [fileName].go

@TODO: 暂时没找到指定临时工作目录的方法。

不拘泥,莫执念

金融街笔记20180605

亲人或余悲,他人亦已歌。 当我们为曾经的错误而哭泣,或彼此伤害的时候,他人早已经放声歌唱,享受夜夜笙歌。

经常用这两句诗提醒自己,开始新生活,开启新篇章。不拘泥,莫执念

不拘泥还有一层含义,拘泥是自己处在窠臼之中,未必是别人推你进去,可能是自己主动进入窠臼,而且乐在其中。

每一个窠臼都提供了幻想的避风港。

常用第三方包

常用第三方包

包的介绍

包类似Java中概念,jar 是源代码管理,分发的最小单位。

目前多数包来自 Github 官方包来自 golang.org/x/...

可以在如下网址查询到高频使用的第三方包清单 https://godoc.org

常用清单

  1. github.com/astaxie/beego 成熟稳定的Web框架,包含更过的Web Framework特性 国内开发者 astaxie
  2. github.com/go-redis/redis 连接Redis
  3. github.com/gomodule/redigo/redis 连接Redis
  4. github.com/jinzhu/gorm 数据库ORM框架,类似Java领域的HibernateMyBatis 国内开发者
  5. github.com/sirupsen/logrus 日志框架,类似Java领域的log4j
  6. github.com/robfig/cron 定时任务,类似Java领域的Quartz
  7. github.com/gin-gonic/gin 精巧高效的Web框架,多用于提供Web服务

时间戳

JavaScriptGolang的时间戳

在计算cookie的有效期时,前端使用JavaScript的时间戳, 后端使用Golang获得时间戳,比较确认是否在有效期内。

但是Golang Unix 时间戳的时间零点和JavaScript的时间零点一致,但是时间单位不同。

JavaScript

  • 时间零点 1970-01-01
  • 时间单位 毫秒

Golang UnixNao

  • 时间零点 1970-01-01
  • 时间单位 秒或纳秒

设计方法 TimeToJavaScriptTimeGolang的时间类型转换成相对于1970-01-01的毫秒

JavaScript

1
2
3
4
> x =new Date()
2018-10-28T10:08:38.546Z
> x.getTime()
1540721318546

Golang

1
2
3
4
5
func TimeToJavaScriptTime(dtNow time.Time) int64 {
dtMark, _ := time.Parse("20060102", "19700101")
dur := dtNow.Sub(dtMark)
return dur.Nanoseconds() / 1e6
}

上述方法存在如下包中,欢迎引入

github.com/devuser/golang-notes/webutils

一把茶壶

金融街笔记20180607

早些年经常去三里屯地下散步,看看各种店铺,和电器超市。某一天在一家日式风格店里看到一把茶壶,很是欢喜,价格1500不贵。但是这茶壶拿回去很容易碎,碎掉后这价格就太贵了。忍着。

承诺自己年底赚到一百万,就过来秒杀这把茶壶。

年底赚到一百万,再回到这家店里把玩这把茶壶,价格依旧,我的感觉却没有当初的欢喜。自然也就不会秒杀,这件事情也就不了了之。

世间多少事都是这样呢?设定一个目标,念兹在兹,达成了却失去当初的欢喜。

我们就在这样的轮回中享受过程的欢喜。一个具体物件,一个外化的目标,到终点反而变得没有那么重要。