Go语言快速上手 - 基础语言
引言
ok,终于有时间以及有机会来继续磨练go了,这次先来介绍部分基础的东西
一、什么是Go语言?
1.高性能、高并发;2.语法简单、学习曲线平缓;3.丰富的标准库;4.完善的工具链;5.静态链接;6.快速编译;7.跨平台;8.垃圾回收
二、变化
是否加分号都没事,建议不加
左括号必须要跟函数名后面(同一行)
func main(){
...
}
导入包
包(package)是多个Golang源码的集合,是一种高级的代码复用方案,换言之Golang的【源码复用】建立在package包基础之上。
//package packagename
package go
package main
1.主程序就直接package main即可
2.导入其他包:
首先需要进行初始化go mod
go mod init name //name根据自己的情况取就可以,不需要跟文件夹对应,对应起来更方便使用
此时会产生一个go.mod文件在根文件夹目录下,这个时候再进行导入操作
(1)本地包:
package main
import(
"test/lib" //这里的test就是上面初始化go mod的name,lib则是文件夹名称,也就是包名
)
(2)网络包(github)
import(
"github.com/xxx/xxx"
)
3.导入包时,三种方式(假设导入一个叫做lib的包):
import(
.lib //会将lib包中所有的函数导入,多包导入容易出错,后续可以直接使用包中方法
name lib //起一个别名,后续可以直接利用 name.函数名()来进行使用
_lib //匿名,可以使用与不使用,同时将会无法使用当前包的方法,但是会执行当前的包内部的init()方法
)
隐匿方式可以用来隐藏不使用的值,这样程序也不会报错
变量
四种变量的声明方式
方法1:声明一个变量 默认的值是0
var a int //此时的值为0(a = 0)
方法2:声明一个变量 初始化一个值
var b int = 100 //此时的值为100(b = 100)
方法3:在初始化的时候,可以省去数据类型,通过值自动匹配当前的变量的数据类型
var c = 100 //此时的值为100,type为int
方法4:省去var关键字,直接自动匹配(常用的方法)
e := 100 //":"这里指初始化,"="指赋值
全局变量的声明
方法1、2、3都可以直接声明全局变量
var gA int = 100
var gB = 200
而方法4只能在函数体内使用
func main(){
gC := 100
}
多个变量的声明
单行:
var xx, yy int = 100, 200 //xx = 100, yy = 200
var kk, ll = 100, "abcd" //kk = 100, ll = abcd
多行:
var(
vv int = 100
jj bool = true
)
常量
1.用const描述常量(只读属性,不允许修改):
const length int = 10
2.可以利用const()来定义枚举类型(可以在const()添加一个关键字iota,每行的iota都会累加1,第一行的iota的默认值是0)
const(
BEIJING = iota //iota = 0
SHANGHAI //iota = 1
SHENZHEN //iota = 2
)
//可以对iota进行乘法
const(
BEIJING = iota*10 //iota = 0
SHANGHAI //iota = 10
SHENZHEN //iota = 20
)
拓展:乘法加法皆可,两个数一起也可以(易错)
const(
a, b = iota + 1, iota + 2 //iota = 0, a = iota + 1, b = iota + 2, a = 1, b = 2
c, d //iota = 1, c = iota + 1, b = iota + 2, c = 2, d = 3
e, f //iota = 2
g, h = iota * 2, iota * 3 //iota = 3, g = iota * 2, h = iota * 3, g = 6, h = 9
i, k //iota = 4
)
并且iota只能在const()中使用,iota只有在const()中进行累加效果
自定义函数
形式:
func foo1(a string, b int){
...
return
}
返回值要与括号前的类型进行匹配:
//返回单个值
func foo1(a string, b int)int {
c:=100
return c
}
//返回多个值
func foo2(a string, b int)(int,int){
return 666, 777
}
//返回多个值,有形参名称的
func foo3(a string, b int)(r1 int, r2 int){ //r1r2如果同类型也可以写成r1,r2 int
r1 = 1000 //即便r1r2没赋值,直接在return处写return 666,777 也照样会对应赋值给r1与r2
r2 = 2000
return
}
如果返回值在函数中没有赋值,默认初始值给的是0(上方程序r1、r2初始值为0),作用空间在整个函数体内。
Defer
defer是用来调用语句的顺序
1.使用:(先写的defer先入栈,后写的defer先出栈)
func main(){
defer fmt.Println("end1")
defer fmt.Println("end2")
fmt.Println("go1")
fmt.Println("go2")
}
// 结果:go1;go2;end2;end1
2.注意:return之后的语句先执行,defer后的语句后执行。函数生命周期结束之后,defer才会出栈
package main
import "fmt"
func deferFunc() int{
fmt.Println("defer1")
return 0
}
func returnFunc() int{
fmt.Println("return1")
return 0
}
func returnanddefer int{
defer deferFunc()
return returnFunc()
}
func main(){
returnanddefer() //结果:return1;defer1
}
循环:
1.for后面的参数不用加括号
2.只有for,可以不加参数无限循环
for i:=1 ; i<=9 ; i++{
...
}
for {
fmt.println()
break
}
switch
1.识别到对应的case后如果没有continue会直接跳出switch;(在C++中,每个case下面不加break的话,即便识别到了case,也会继续逐一识别下面的case)
2.后面的参数也不需要加括号
3.甚至可以替代if else,switch后面不写参数,在case中写条件
t := time.Now()
switch{
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}