当前位置:   article > 正文

Go基础入门_go入门

go入门

Go语言介绍

解释型语言和编译型语言的区别。

image-20210625104252453

Go语言是编译型语言。

Go语言的特点(自带垃圾回收,天生支持并发)

  • 语法简洁
  • 开发效率高
  • 执行性能好

Go的依赖管理

为什么需要依赖管理

最早的时候,Go所依赖的所有第三方库都在GOPATH目录下,这就导致同一个库只能保存在一个版本的代码,如果不同的项目依赖同一个库的不同版本,就没办法了。

godep

从1.5开始引入vendor模式,如果项目目录下有vendor目录,那么go工具链就会优先使用vender内的包进行编译,测试等。

godep是一个通过vender模式实现的Go语言的第三方依赖管理工具,类似的还有社区维护的包管理工具dep。

安装godep

go get github.com/tools/godep

在终端输入godep查看支持的所有命令

image-20210625114049750

使用godep save命令,会在当前项目中创建Godeps和vender两个文件夹,其中Godeps文件夹下有一个Godeps.json的文件,里面记录了项目所依赖的包信息。vender文件夹下是项目依赖的包的源代码文件。

vender机制

Go1.5版本之后开始支持,能够控制Go语言程序编译时依赖包搜索路径的优先级。

例如查找项目的某个依赖包,首先会在项目根目录下的vender文件夹中查找,如果没有找到就会去$GOAPTH/src目录下查找。

包和文件

在Go语言中,如果导入了一个包但是没有使用该包,将被当做一个编译错误处理,这种强制规则可以有效减少不必要的依赖。goimports工具可以根据需要自动添加或者删除导入的包,许多编辑器都可集成这个工具,然后保存文件自动运行,gofmt工具可以用来格式化Go文件。

包的初始化首先是解决包级别变量的依赖顺序,然后按照包级别变量声明出现的顺序依次初始化。

包中一般含有多个go源文件,他们将按照发给编译器的顺序进行初始化,Go语言的构建工具首先会将go文件根据文件名进行排序,然后依次调用编译器编译。

init初始化函数

每个文件都可以包含多个init初始化函数,这样的初始化函数除了不能被调用或者引用外,其他行为和普通函数类似。在每个文件中的init初始化函数,在程序开始执行时按照他们声明的顺序被自动调用。

func init(){
   
    
}
  • 1
  • 2
  • 3
  • 4

每个包只会被初始化一次,如果p包导入了另一个包p,那么p在初始化的时候q就必然已经初始化过了。所以main包是最后被初始化的。

变量和常量

函数外面只能放标识符(变量,常量,函数,类型)的声明。

Go语言必须先声明再使用。

常量表达式的值在编译期进行计算,而不是在运行期,每种常量的潜在类型都是基础类型或数字。常量一旦赋值不可修改,值不会改变。

标识符

在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符由字母数字和_(下划线)组成,并且只能以字母和_开头。 举几个例子:abc, _, _123, a123

关键字

关键字是指编程语言中预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。

Go语言中有25个关键字:

    break        default      func         interface    select
    case         defer        go           map          struct
    chan         else         goto         package      switch
    const        fallthrough  if           range        type
    continue     for          import       return       var
  • 1
  • 2
  • 3
  • 4
  • 5

此外,Go语言中还有37个保留字。

    Constants:    true  false  iota  nil

        Types:    int  int8  int16  int32  int64  
                  uint  uint8  uint16  uint32  uint64  uintptr
                  float32  float64  complex128  complex64
                  bool  byte  rune  string  error

    Functions:   make  len  cap  new  append  copy  close  delete
                 complex  real  imag
                 panic  recover
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

变量

变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号。 举个例子:

// 标准声明
var studentName string

// 批量声明
var (
	age  int
	isOk bool
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

变量的初始化

Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil。出现在赋值语句的右边时,并不一定是产生两个结果,也可能产生两个结果。对于值产生一个结果的情形,map 查找失败时会返回零值,类型断言失败时会发送运行时panic异常,通道接收失败时会返回零值(阻塞不算是失败)。

var name string = "Q1mi"
var age int = 18
var name, times = "Q1mi", 20
  • 1
  • 2
  • 3

我们可以直接将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。

var name = "Q1mi"
var age = 18
  • 1
  • 2

短变量声明

在函数内部,可以使用更简略的 := 方式声明并初始化变量,函数外面不能使用简短声明。

func testNum() {
   
	n := 10
	m := 200 // 此处声明局部变量m
	fmt.Println(m, n)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

匿名变量

在使用多重赋值的时候,如果想要忽略某个值,可以使用_接收_,表示一个匿名变量。

匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。在lua编程语言中,匿名变量也叫做哑元变量。

func foo() (int, string) {
   
	return 100, "hehe"
}
func main() {
   
	// _ 匿名变量,相当于占位符
	_, str := foo()
	fmt.Println(str)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

注意事项:

  1. 函数外的每个语句都必须以关键字开始(var、const、func等)
  2. :=不能使用在函数外。
  3. _多用于占位,表示忽略值。
  4. 局部变量声明后,必须使用,否则会编译报错。

类型

在赋值语句两边的变量最终的值必须有相同的数据类型。

新命名的类型提供了一个方法,用来分割不同概念的类型,这样即使他们底层类型相同也是不兼容的。

type 类型名称 底层类型
type num int
  • 1
  • 2

类型声明的语句一般出现在包一级,如果新创建的类型名字的首字母大写,那么在外部包也可以使用。

对于中文汉字,Unicode标志都作为小写字母处理,因此中文的命名默认不能导出。

对于每个类型T,都有一个类型转换操作T(x),将x转换成T类型,如果是指针烈性,可能要用小括号包装T,(*int)(0)。只有当两个类型的底层基础类型相同时,才允许这种转型,或者是两者都是指向相同底层结构的指针类型,这些转换值改变类型而不会影响值本身。

如果两个值有着不同的类型,则不能直接比较。编译会报错。

var	c	Celsius 
var	f	Fahrenheit
fmt.Println(c	==	0)										//	"true"
fmt.Println(f	>=	0)										//	"true"
fmt.Println(c	==	f)										//	compile	error:	type	mismatch
fmt.Println(c	==	Celsius(f))	//	"true"!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

常量

对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const,常量在定义的时候必须赋值。

const pi = 3.1415
const e = 2.7182
  • 1
  • 2

声明了pie这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。

多个常量也可以一起声明:

const (
    pi = 3.1415
    e = 2.7182
)
  • 1
  • 2
  • 3
  • 4

const同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:

const (
    n1 = 100
    n2
    n3
)
  • 1
  • 2
  • 3
  • 4
  • 5

上面示例中,常量n1n2n3的值都是100。

常量计数器iota

iota是go语言的常量计数器,只能在常量的表达式中使用。

iota在const关键字出现时将被重置为0,const中每次增加一行常量声明将使iota计数一次,使用iota能简化定义,在定义枚举时很有用。

const (
	n1 = iota //0
	n2        //1
	_
	n4 //3
	_  = iota
	KB = 1 << (10 * iota)
	MB = 1 << (10 * iota)
	GB = 1 << (10 * iota) //从这开始会溢出
	TB = 1 << (10 * iota)
	PB = 1 << (10 * iota)
)

func main(){
   
    fmt.Println(n1)
	fmt.Println(n2)
	fmt.Println(n4)
	fmt.Println(KB)
	fmt.Println(MB)
}
// 输出
0
1
3
1125899906842624
1152921504606846976
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

进制输出

%d:十进制

%o:八进制

%x:十六进制

%b:二进制

%T:输出数据类型

%c:字符

%s:字符串

%p:指针

%v:值

%#v:详细值

%f:浮点数

%t:bool值

func main() {
   

	i2 := 077
	fmt.Printf("十进制:%d\n", i2)
	fmt.Printf("二进制:%b\n", i2)
	fmt.Printf("八进制:%o\n", i2)
	fmt.Printf("十六进制:%x\n", i2)
	fmt.Printf("数据类型:%T\n", i2)
	//强制类型转换
	fmt.Printf("%d", int32(i2))
}
/**十进制:63
二进制:111111
八进制:77
十六进制:3f
数据类型:int
63**/

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

数据类型

uint8 无符号 8位整型 (0 到 255)
uint16 无符号 16位整型 (0 到 65535)
uint32 无符号 32位整型 (0 到 4294967295)
uint64 无符号 64位整型 (0 到 18446744073709551615)
int8 有符号 8位整型 (-128 到 127)
int16 有符号 16位整型 (-32768 到 32767)
int32 有符号 32位整型 (-2147483648 到 2147483647)
int64 有符号 64位整型 (-9223372036854775808 到 9223372036854775807)

特殊整型

类型 描述
uint 32位操作系统上就是uint32,64位操作系统上就是uint64
int 32位操作系统上就是int32,64位操作系统上就是int64
uintptr 无符号整型,用于存放一个指针

注意: 在使用intuint类型时,不能假定它是32位或64位的整型,而是考虑intuint可能在不同平台上的差异。

获取对象长度的内建len()函数返回的长度可根据不同的平台的字节长度进行变化,实际使用中,切片或map的元素数量等都可以用int来表示,但是在进行二进制传输,读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int和uint。

浮点类型

Go语言支持两种浮点类型:float32和float64,这两种浮点类型数据格式遵循IEEE754标准,float32的浮点数的最大范围是3.4e38,可以使用常量定义:math_MaxFloat32,float64的浮点数的最大范围大约是1.8e308,可以使用常量定义:math.MaxFloat64。默认是float64位类型。

%f:表示浮点数输出类型

math包中除了提供大量常用的数学函数之外,还提供了IEEE754浮点数标准中定义的特殊值的创建和测试:正无穷大和负无穷大,分别用于表示太大溢出的数字和除零的结果,NaN表示无效的除法操作0/0或者Sqrt(-1)

NaN和任何数都是不相等的(译注:在浮点数中,NaN、正无穷大和负无穷大都不是唯一 的,每个都有非常多种的bit模式表示)

数组是值类型,值传递(复制一份,在新数据上修改,原先数据不受影响)

复数

complex64和complex128,分别对

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/624089
推荐阅读
相关标签
  

闽ICP备14008679号