go语言常用知识(一)
写在前面
Golang 在各平台安装的教程网上都有很多,这里说一下几个环境变量的含义,刚开始往往会只跟着配环境而搞不清楚各个变量的具体意思
- GOPATH:实际上是GO语言的工作目录,在Linux系统下,需要自己去指定,并创建
src(项目源码)
,pkg(编译后生成文件)
和bin(编译后可执行文件)
三个目录。使用go get
命令可以直接下载第三方的包到自己的项目的src下和相关的执行文件bin目录,和中间文件pkg。这一点很重要,后面使用go.mod的时候,可以直接在mod文件里指定依赖包,build时再下载相关包,很方便。在写真正的大型golang系统时需要重点关注此目录,仅仅想跑个简单go代码,甚至可以不用管这个目录 - GOROOT:是golang的安装路径,现在版本的go安装包在安装后自动给你配置好这个路径了,可以不用管,Linux系统下一般为
/usr/local/go
- PATH:这个就是指向
bin
文件夹的,和Java的PATH没什么区别
交叉编译
在Windows平台编译一个能在Linux平台执行的可执行文件
SET CGO_ENABLED=0 //禁用CGO
SET GOOS=linux //目标平台Linux
SET GOARCH=amd64 //目标处理器架构是amd64
在Mac下编译Linux和Windows平台64位可执行程序
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
在Linux下编译Mac和Windows平台64位可执行程序
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
变量相关
声明变量
var name string
var (
name string
age int
isOk bool
)
go语言中非全局变量声明必须使用,不使用就编译不过去
输出变量时,可以用占位符
fmt.Printf("name:%s",name)
声明变量同时赋值
var s1 string = "zhangsan"
类型推导(省略变量类型,编译器根据等号右边值来推导变量类型完成初始化)
var name = "QQQ"
var age = 18
短变量声明
- 函数内部,可以用更简略的
:=
方式声明并初始化变量
func main(){
s3:="s3"
}
匿名变量
- 多重赋值,想要忽略某个值,使用
匿名变量
,匿名变量用一个下划线_
表示
func foo(int,string){
return 10,"xxx"
}
func main(){
x,_ :=foo()
_,y :=foo()
fmt.Println(x)
fmt.Println(y)
}
- 函数外的每个语句必须以关键字开始(func,var,const等)
- 函数外不能使用
:=
简易声明赋值 _
多用于占位,表示忽略值
iota
- 常量计数器,只能在常量表达式中使用
iota
在const关键字出现时被重置为0。const中每新增一行常量声明将使iota
计数一次(iota可以理解为const语句块中的行索引)。经常用来简化定义,定义枚举
const(
n1 = iota //0
n2 //1
n3 //2
n4 //3
)
整型
var i1 = 101
fmt.Printf("%d\n", i1)
//八进制
i2 := 077
fmt.Printf("%o\n", i2)
fmt.Printf("%d\n", i2)
fmt.Printf("%b\n", i2)
//十六进制
i3 := 0x1234567
fmt.Printf("%x\n", i3)
//查看变量类型
fmt.Printf("%T\n", i3)
字符串相关
无法直接修改,字符串变量相当于常量
将字符串变量使用 byte或rune存储和处理
s1 := "白胡子"
s2 := []rune(s1)
s2[0] = '黑'
fmt.Println(string(s2))
for循环
可以用break
、goto
、return
、panic
语句强制退出循环
Go语言中可以使用for range
遍历数组、切片、字符串、map及通道(channel),通过for range
遍历的返回值有以下规律:
- 数组、切片、字符串返回索引和值
- map返回键和值
- 通道(channel)只返回通道内的值
s1 := []rune("白胡子")
for i, v := range s1 {
fmt.Printf("第%d个为%c\n", i, v)
}
out:
第0个为白
第1个为胡
第2个为子
goto语句,直接跳到相应标签执行
func main() {
s1 := []rune("白胡子")
for i, v := range s1 {
if i > 0 {
goto xxx
}
fmt.Printf("第%d个为%c\n", i, v)
}
xxx:
fmt.Print("跳出")
}
数组
声明时就确定,指定元素类型和容量
初始化方法
//初始化定长
a0 := [3]int{1, 2, 3}
fmt.Print(a0)
//根据数组长度自适应
a1 := [...]int{1, 2, 3, 4, 5}
fmt.Print(a1)
//指定索引
a2 := [5]int{0: 1, 4: 2}
fmt.Print(a2)
指针
&
取地址,*
根据地址取值
内存分配(make和new的区别)
- make都new都是用来申请内存的
- new用的较少,一般给基本数据类型申请内存
- make是用来给slice、map、chan申请内存的,make函数返回的是对应的这三个类型本身
map
提供映射关系的容易,内部使用Hash(散列表)实现
- map定义
- map[keyTpye]ValueType
- 定义后需要赋予空间