Go语言快速上手 - 基础语言(1)|青训营

95 阅读5分钟

Go语言快速上手 - 基础语言

引言

ok,终于有时间以及有机会来继续磨练go了,这次先来介绍部分基础的东西

一、什么是Go语言?

1.高性能、高并发;2.语法简单、学习曲线平缓;3.丰富的标准库;4.完善的工具链;5.静态链接;6.快速编译;7.跨平台;8.垃圾回收

二、变化

是否加分号都没事,建议不加

左括号必须要跟函数名后面(同一行)

func main(){
  ...
}

导入包

包(package)是多个Golang源码的集合,是一种高级的代码复用方案,换言之Golang的【源码复用】建立在package包基础之上。

//package packagename
package go
package main

www.jianshu.com/p/7ebe1bc7e…

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")
}