GO语言02(常用子命令,变量和数据类型)

目录

GO常用管理子命令

1. 介绍

2. 常用命令汇总

3. go build

4. go run

5. go install

6. go get

7. go fmt

8. go tool

变量

1. 变量定义

GO的数据类型

1. 简单类型

2. Go 语言类型转换

3. 数组(array)与切片(slice)

4. 字典(键值对,map)

5.指针(pointer)

6. nil零值

7. type

8. 数据的存储

9. 常量声明


GO常用管理子命令

1. 介绍

Go 语言中,我们很多操作都是通过 go 命令进行的,比如我们要执行 go 文件的编译,就需要使用 go build 命令, 除了 build 命令之外,还有很多常用的命令,这一次我们就统一进行介绍,对常用命令有一个了解,这样我们就可 以更容易的开发我们的Go 程序了。
go 这个工具,别看名字短小,其实非常强大,是一个强大的开发工具。

2. 常用命令汇总

go version: 获取Go版本 
go env: 查看Go环境变量 
go help: 查看Go帮助命令 
go get: 获取远程包(需提前安装git或hg) 
go build: 编译并生成可执行程序 
go run: 直接运行程序 
go fmt: 格式化源码 
go install: 编译包文件以及整个程序 
go test: go原生提供的单元测试命令 
go clean: 移除当前源码包和关联源码包里编译生成的文件 
go tool: 升级Go版本时,修复旧版代码 
godoc -http:80:开启一个本地80端口的web文档 
gdb 可执行程序名:调试Go编译出来的文件

使用格式:
go command [arguments]

3. go build

go build ,它可以启动编译,把我们的包和相关的依赖编译成 一个可执行的文件
如果是 main 包,执行 go build 之后,会在当前目录下生成一个可执行文件。
示例:
// 编译当前目录为一个可执行文件
go build 
// 编译当前目录为一个可执行文件 
go build . 
// 编译hello.go文件为一个可执行文件 
go build hello.go

如果go build报错:
/usr/lib/go-1.10/pkg/tool/linux_amd64/link: running gcc failed: exit status 1 
/tmp/go-link-008006128/000026.o: In function _cgo_05dc84caff82_Cfunc_sysconf': 
/tmp/go-build/cgo-gcc-prolog:32: multiple definition 
of_cgo_05dc84caff82_Cfunc_sysconf’ 
/tmp/go-link-008006128/000024.o:/tmp/go-build/cgo-gcc-prolog:32: first defined here collect2: error: ld returned 1 exit status

解决办法:
linux: export CGO_ENABLED=0 
windows : cmd: set CGO_ENABLED=0 
windows : powershell:$env:CGO_ENABLED=0

4. go run

go build 是先编译,然后我们在执行可以执行文件来运行我们的程序,需要两步。
go run 这个命令就是可以把这两步合成一步的命令,节省了我们录入的时间
命令格式:
go run 文件名.go
示例:
go run main.go

5. go install

go install 命令和 go build 类似,用来生成项目的可执行文件。不过它可以在编译后,把生成的可执行文件或者 库安装到对应的目录下,以供使用。
可执行文件安装到: $GOPATH/bin/
可引用库安装到: $GOPATH/pkg/
注意: 没有开启go mod时,使用上述命令需要配置GOPATH,否则会报:no install location。

6. go get

go get 用来获取远程仓库中的包,使用该命令前必须配置 GOPATH, 而且依据不同的源码网站,还要安装不同的版本管 理工具,比如从github 上使用 go get 需要额外安装 git
go get 本质上可以理解为通过源码工具 clone 下代码后,执行了 go install
命令格式:
下载包:添加 -u 参数可以自动更新包和依赖
go get github.com/**/**

使用安装的包
import "github.com/****/****"

如果下载慢,记得配置goproxy
# 设置module管理模式 
$ go env -w GO111MODULE=on 
# 设置下载源 
$ go env -w GOPROXY=https://goproxy.cn

7. go fmt

go fmt命令可以格式化代码文件                                                                                                       使用go fmt命令,其实是调用了gofmt,而且需要参数-w,否则格式化结果不会写入文件

命令格式:
go fmt -w 文件名.go
示例:格式化整个项目
gofmt -w -l src
常见参数:
-l: 显示那些需要格式化的文件 
-w: 把改写后的内容直接写入到文件中,而不是作为结果打印到标准输出。 
-r: 添加形如"a[b:len(a)] -> a[b:]"的重写规则,方便我们做批量替换 
-s: 简化文件中的代码 
-d: 显示格式化前后的diff而不是写入文件,默认是false 
-e: 打印语法错误到标准输出。无此参数只会打印不同行的前10个错误。

8. go tool

go tool 下聚集了很多命令,主要有 2 个,即 fifix vet
go tool fix .:用来修复以前老版本的代码到新版本 
go tool vet directory|files:分析当前目录的代码是否正确

变量

1. 变量定义

 Go 语言是静态类型的,变量声明时必须明确变量的类型。                                                           Go 语言与其他语言显著不同的一个地方在于,Go 语言的类型在变量后面。比如 java 中,声明一个整体一般写成 int a = 1,在 Go 语言中,需要这么写:

格式1:`var identifier type`
    这种关键字的写法一般用于声明全局变量
var a int         // 如果没有赋值,默认为0
var a int = 1     // 声明时赋值
var a = 1         // 声明时赋值
`var a = 1`,因为 1 是 int 类型的,所以赋值时,a 自动被确定为 int 类型,所以类型名可以省略不写

格式2:还有一种更简单的表达
// 这种方式相对来说用得更多一些
a := 1
msg := "Hello World!"

格式3:一次声明多个变量`var identifier1, identifier2 type`
var b, c int = 1, 2

**注意**:
* 变量需要定义后再使用
* := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
* 变量定义后没有使用编译会失败 **a declared but not used**
* go会根据值确定类型,也会根据类型自动确定值

GO的数据类型

Go的数据类型分为四大类:

基础类型----数字、字符串、布尔型

聚合类型----数组、结构体

引用类型----指针、slice、map、函数、管道

接口类型

1. 简单类型

简单例子:
package main

import (
	"fmt"
	// 反射模块,核心包括两方面:类型(reflect.Type)、值(reflect.Value)
	"reflect"
)

func main() {
    str1 := "Golang"
    str2 := "Go语言"
    var a int8 = 10
	var c1 byte = 'a'
	var b float32 = 12.2
	var msg = "Hello World"
	ok := false
    fmt.Println(reflect.TypeOf(str2[2])) // uint8
    fmt.Println(str1[2], string(str1[2]))       // 108 l
    fmt.Printf("%d %c\n", str2[2], str2[2])     // 232 è
    fmt.Println("len(str2):", len(str2))       // len(str2): 8
}

2. Go 语言类型转换

类型转换用于将一种数据类型的变量转换为另外一种类型的变量。Go 语言类型转换基本格式如下:

type_name(expression)
* type_name 为类型
* expression 为表达式

以下实例中将整型转化为浮点型,并计算结果,将结果赋值给浮点型变量:
package main

import "fmt"

func main() {
  var sum int = 17
  var count int = 5
  var mean float32

  mean = float32(sum)/float32(count)
  fmt.Printf("mean 的值为: %f\n",mean)
}
以上实例执行输出结果为:
mean 的值为: 3.400000

3. 数组(array)与切片(slice)

Go 语言提供了数组类型的数据结构。

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。

数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:

一维数组的定义
var variable_name [SIZE] variable_type

定义了数组 balance 长度为 5 类型为 float32
var balance [5] float32
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

如果设置了数组的长度,我们还可以通过指定下标来初始化元素:
//  将索引为 1 和 3 的元素初始化
balance := [5]float32{1:2.0,3:7.0}

如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

数组取值
// 下标取值 
variable_name[n]
// 切片取值
variable_name[slice]

综合小案例
arr := [5]int{1, 2, 3, 4, 5}
for i := 0; i < len(arr); i++ {
	arr[i] += 100
}
fmt.Println(arr)  // [101 102 103 104 105]

二维数组 
var variable_name [SIZE][SIZE] variable_type
定义了数组 balance 长度为 10 *10类型为 float32
var balance  [10][10]float32






4. 字典(键值对,map)

map 类似于 java 的 HashMap,Python的字典(dict),是一种存储键值对(Key-Value)的数据解构。使用方式和其他语言几乎没有区别。

// 仅声明
m1 := make(map[string]int)
// 声明时初始化
m2 := map[string]string{
	"Sam": "Male",
	"Alice": "Female",
}
// 赋值/修改
m1["Tom"] = 18

5.指针(pointer)

指针即某个值的地址,类型定义时使用符号*,对一个已经存在的变量,使用 & 获取该变量的地址。

str := "Golang"
var p *string = &str // p 是指向 str 的指针
*p = "Hello"
fmt.Println(str) // Hello 修改了 p,str 的值也发生了改变

一般来说,指针通常在函数传递参数,或者给某个类型定义新的方法时使用。Go 语言中,参数是按值传递的,如果不使用指针,函数内部将会拷贝一份参数的副本,对参数的修改并不会影响到外部变量的值。如果参数使用指针,对参数的传递将会影响到外部变量。例如:

func add(num int) {
	num += 1
}

func realAdd(num *int) {
	*num += 1
}

func main() {
	num := 100
	add(num)
	fmt.Println(num)  // 100,num 没有变化

	realAdd(&num)
	fmt.Println(num)  // 101,指针传递,num 被修改
}
  • reflect.TypeOf().Kind() 可以知道某个变量的类型,我们可以看到,字符串是以 byte 数组形式保存的,类型是 uint8,占1个 byte,打印时需要用 string 进行类型转换,否则打印的是编码值。

  • 因为字符串是以 byte 数组的形式存储的,所以,str2[2] 的值并不等于。str2 的长度 len(str2) 也不是 4,而是 8( Go 占 2 byte,语言占 6 byte)。                                           正确的处理方式是将 string 转为 rune 数组 

str2 := "Go语言"
runeArr := []rune(str2)
fmt.Println(reflect.TypeOf(runeArr[2]).Kind()) // int32
fmt.Println(runeArr[2], string(runeArr[2]))    // 35821 语
fmt.Println("len(runeArr):", len(runeArr))    // len(runeArr): 4

转换成 `[]rune` 类型后,字符串中的每个字符,无论占多少个字节都用 int32 来表示,因而可以正确处理中文。

6. nil零值

nil是go语言中预先的标识符,我们可以直接使用nil,而不用声明它。

nil的常用写法:
file,err := funcName(xxx)
if err!= nil{
	// do something....
	fmt.Println("代码有错误")
}
* 获取函数返回值,其中当err不等于`nil`的时候,说明出现某些错误了,需要我们对这个错误进行一些处理
* 如果err等于`nil`说明运行正常。

那什么是nil呢?

nil的意思是无,或者是零值。

在Go语言中,如果你声明了一个变量但是没有对它进行赋值操作,那么这个变量就会有一个类型的默认零值。这是每种类型都有不同对应的零值:

nil的值类型必须是指针、通道、func、接口、映射或切片类型

类型定义零值
boolvar variable boolfalse
intvar variable int0
stringvar variable string""
pointersvar a *intnil
slicesnil
mapsnil
channelsnil
functionsnil
interfacesnil

7. type

Go语言中type关键字用于定义类型,因此又称为类型别名。

理解了type关键字就会很容易理解Go语言中的函数、结构体、接口等。

使用`type`关键字定义类型
type NewType BaseType

类型定义是基于底层类型(BaseType)创建全新的类型(NewType),类型定义创建的是一个全新的类型,与其所基于的类型是两个不同的类型。
type math func(int, int) int //定义一个函数类型,两个 int 参数,一个 int 返回值

//定义一个函数 add,这个函数两个 int 参数一个 int 返回值,与 math 类型相符
func add(i int, j int) int {
    return i + j
}

8. 数据的存储

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:

当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝:  

 

 

你可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)。

值类型变量的值存储在堆中。

内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同。

更复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存。

一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。

这个内存地址称之为指针,这个指针实际上也被存在另外的某一个值中。

同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。

当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。

如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。

9. 常量声明

常量是一个简单值的标识符,在程序运行时,不会被修改的量。

常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。

常量的定义格式:
const identifier [type] = value

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。
- 显式类型定义: `const b string = "abc"`
- 隐式类型定义: `const b = "abc"`
多个相同类型的声明可以简写为:
const c_name1, c_name2 = value1, value2

以下实例演示了常量的应用:
package main
import "fmt"

func main() {
  const LENGTH int = 10
  const WIDTH int = 5  
  var area int
  const a, b, c = 1, false, "str"  //多重赋值

  area = LENGTH * WIDTH
  fmt.Printf("面积为 : %d", area)
  println()
  println(a, b, c)  
}

以上实例运行结果为:
面积为 : 50
1 false str

常量还可以用作枚举:
const (
    Unknown = 0
    Female = 1
    Male = 2
)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值