今天开始学Go(一)

今天开始学Go,包管理(一)

Node.js和Go之间,我选择Go。因为最年来太火了。之前在14年的时候也开始接触Go,但没有坚持学下来。下面是我写的两篇文章,太久了,不建议去看了。记录下当时入门的心态。

拖延症这是永恒话题。下面记录我学Go的一些总结。目前我使用的是Go version 1.10.2。由于网上各种安装教程,go的命令行,这里我就不开篇去写。

1. Package 包管理

和Node.js不同,Go自带包管理器。
Go命令行有三个命令是和包管理有很重要的关系的。

go get
go install
go list

在将Go包管理之前,我先讲下Go的环境变量。

a. 环境变量$GOPATH
  • GOPATH
    在使用go tour的时候,在使用get命令去获取tour的时候一直不会报错,也没有提示成功。
    go get github.com/golang/tour/gotour // go get golang.org/x/tour/gotour已经被墙

查看了文档,是因为没有配置GOPATH的环境变量。在Mac中,我使用的是brew安装的go。在安装完之后,我查看了一下GO的环境

go env

发现显示的没有问题,所以我没有配置环境变量

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/nico/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/nico/go/bin"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.2/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.2/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config

再深挖一层。GOPATH是GO引入包的最重要条件。所以我在.bash中设置了$GOPATH以及$PATH.
配置完$GOPATH后,可以在$GOPATH/src安装第三方包,可以使用go get或者直接download在$GOPATH/src里面。

GOPATH=$(go env GOPATH)/bin
export PATH=${PATH}:${GROWING_IO}:${JAVA_HOME}/bin:${APACHE_MAVEN}:${GOPATH}
export GOPATH

b. go get

这条命令在我的理解里,它做了那么一件事情:将第三方包(除了go自身的所含有的包之外的我管它成为第三方包)下载到本机,也就是GOPATH目录中的src下面。
比如想要装这个包:github.com/golang/tour

go get github.com/golang/tour

那么会在$GOPATH/src下会发现github.com/golang/tour这样的一个层级的目录。下载的包就在里面。
注意些问题,假如被墙了,那么只能手动的去下载包,然后就可以使用go install

b. go install

安装包

c. go list

查看包

d. vendor

在GO v1.5版本之后,官方加入了vendor这个包管理的选项。它是默认打开的。它的效果相当于Node.js中的node_modules,所以这对前端来说学习成本是比较低的。

e. 总结

对于Node.js来说,GO的包管理是一个很烂的设计。在Node.js中,npm和yarn就已经很好的解决版本依赖问题,也有一套规范。但是在我看来GO还是很弱的。好在社区给力,GO官方也提供了一些建议,应该使用第三方包管理。
之后,我在使用GO的时候会去使用glide作为第三方包管理器。原因很简单,与npm接近,glide操作的是vendor。省去很多学习成本。

2. Import

GO中引入包的方式和Javascript的引用方式大体是一样的。比如想要引入一个math包的时候,可以这么使用

import 'math'

当使用多个引用的时候可以使用一个函数import(),这和Javascript中是不一样的,比如:

import (
'fmt',
'math'
)

然后在下文中就可以愉快的使用了。
在这里需要注意的一点是,一个go官方的推荐的,包名是一个单词,并且是小写。package-names

3. Export

在GO中,名称为大写则被导出。不是大写则不会被导出。例如

package main

import (
"fmt",
"math"
)

func main() {
fmt.Print(math.Pi)
}

4. Functions

先看示例代码:

package main

import "fmt"

func add1(int x, int y) int {
return x + y
}

func add2(x, y int) int {
return x + y
}

func swap(x, y string) (string, string) {
return y, x
}

func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(add1(44, 13))
fmt.Println(add2(44, 13))
a, b := swap("hello", "world")
fmt.Println(a, b)
fmt.Println(split(17))
}

从上面的代码中,GO的方法,可以总结一些规则出来。

a. 声明

在GO中定义方法,只需要func + 方法名就可以了

b. 参数

在GO中,有两种定义参数的格式
一、每一个参数定义一个类型,如:

func add1(int x, int y) int {
return x + y
}

二、同类型简写

func add2(x, y int) int {
return x + y
}

b. 返回值

返回值也有三种类型
一、单个参数形式只需要写返回参数的类型,如:

func add2(x, y int) int {
return x + y
}

二、多个参数返回,如

func swap(x, y string) (string, string) {
return y, x
}

三、多个参数返回,如

func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}

5. Variables 变量

和Javascript一样,Go使用var进行变量声明。但是注意几点:

a. 只声明变量而不赋值的时候,声明的变量为boolean类型,如:
var a b c
fmt.Println(a, b, c) // false false false
b. 声明变量后可赋值
var a = 1
a = 2
fmt.Println(a) // 2
c. Variables with initializers

可以初始化多个变量

var a, b int
fmt.Println(a, b) // 0 0

d. 简短声明

:=仅限于在一个function内部去使用,在function外部需要var去声明变量

a := 'a'
fmt.Println(a) // a

6. 类型

在GO中,GO有以下类型

bool

string

int int8 int16 int32 int64

uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32
// represents a Unicode code point

float32 float64

complex64 complex128

a. GO声明变量但未赋值时,改变量对应的类型默认的value是
  • int/float 0
  • bool false
  • string “”
    b. 类型转换
    GO可以使用 sth.type(variable)做类型转换,比如
    i := 42
    f := float64(i)
    u := uint(f)
c. 常量

与Javascript无区别使用 const 关键字。

6. 语句

a. for

循环语句很简单。

for i := 0; i < 10; i++ {
fmt.Println(i)
}

还有一种写法,i是可短的:

sum := 1
for ; sum < 1000 {
sum += sum
}
fmt.Println(sum) // 1024

Go没有while语法,Go直接使用for作为循环语句

sum := 1
for sum < 1000 {
sum + sum
}
fmt.Println(sum) // 1024

当想要一个无限循环的时候(不建议那么做):

for {}

b. if

if语句与Javascript除了没有括号之外是没有差别的,可以感受一下

a := -1
if a < 0 {
fmt.Println("a is less then zero")
}

除此之外,在if里面还能定义一行语句接着一个true / false的语法,例如

if a := 1; a < 0 {
fmt.Println("a is less then zero")
}

if 语句当然还有else,其用法和Javascript区别不是很大

if a := 1; a < 0 {
fmt.Println("a is less then zero")
} else {
fmt.Println("a is bigger then zero")
}

c. switch

switch和if是差不多的可以定义简短的语句,例如:

switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}

c. defer

函数延迟执行。当深入的时候再看看这个具体怎么去实现的。

文章作者: 韦宗圻
文章链接: https://www.weizongqi.com/2018/05/19/今天开始学Go(一)/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 wiki
支付宝打赏
微信打赏