go基础巩固

go基础巩固

_(下划线)

下划线是一个特殊的变量名,任何赋予它的值都会被丢弃

iota

Go里面有一个关键字iota,这个关键字用来声明enum的时候采用,它默认开始值是0,const中每增加一行加1

make,new操作符

内建函数new本质上说跟其它语言中的同名函数功能一样:new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个*T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。

1
new  返回指针

内建函数make(T, args)与new(T)有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型,而不是*T。本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值

1
make返回初始化后的(非零)值。

goto

goto跳转到必须在当前函数内定义的标签
标签:这行的第一个词,以冒号结束作为标签,标签大小写敏感

1
2
3
4
5
6
7
8
func test() int{
a := 1
HERE:
println(i)
a++
goto HERE

}

switch

go的switch-case结构里面。默认带有break

fallthrough

switch-case ,找到匹配的case值后,默认会跳出结构,fallthrough 关键字 可以强制执行后面的case代码

Go函数支持变参

接受变参的函数是有着不定数量的参数,示例如下:

1
2
3
4
5
6
func test(arg ...int)(x,y int){
// arg 是一个slice结构
for i,v := range arg{

}
}

defer

Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回。

1
2
3
4
5
6
7
8
9
10
11
func ReadWrite() bool {
file.Open("file")
defer file.Close()
if failureX {
return false
}
if failureY {
return false
}
return true
}

main()函数和init()函数

Go里面有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main)
这两个函数在定义时不能有任何的参数和返回值
虽然一个package里面可以写任意多个init函数,但这无论是对于可读性还是以后的可维护性来说,我们都强烈建议用户在一个package中每个文件只写一个init函数
Go程序会自动调用init()和main(),所以你不需要在任何地方调用这两个函数
每个package中的init函数都是可选的,但package main就必须包含一个main函数
注意: main包中,如果既有init()函数也有main函数,会先执行init()函数

import 导入包的几种特殊写法

  1. .导入
    包名前面加点,可以在使用包里面函数的时候,忽略包名

    1
    2
    3
    4
    5
    6
    7
    8
    import (
    ."fmt"
    )

    //不加点使用
    fmt.Println()
    //加点使用
    Println()
  2. 别名操作
    顾名思义,就是可以给包起个别名

    1
    2
    3
    4
    5
    import (
    f "fmt"
    )
    //使用
    f.Println()
  3. _操作
    _的操作,实质不是引入包的函数,而是执行包的init()函数

结构体(自定义类型)

匿名字段(嵌入字段)

当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct
这里有一个问题:如果human里面有一个字段叫做phone,而student也有一个字段叫做phone,那么该怎么办呢?
Go里面很简单的解决了这个问题,最外层的优先访问,也就是当你通过student.phone访问的时候,是访问student里面的字段,而不是human里面的字段。

1
2
3
4
type User struct{
name string
age int
}

interface

简单的说,interface是一组method签名的组合,我们通过interface来定义对象的一组行为
interface可以被任意的对象实现
一个对象可以实现任意多个interface
任意的类型都实现了空interface(我们这样定义:interface{}),也就是包含0个method的interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type User struct{
name string
age int
}
type Student struct{
User
lesson string
}
type Teacher struct{
User
teach_card string
}
func (user User) sing(a string){

}
func(user User) sayHi(){

}
type Men interface{
sing(a string)
sayHi()
}

注意:
一个函数把interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值

嵌入interface

跟嵌入struct字段一样,interface也可以嵌入interface
嵌入其他interface,该interface就会拥有其他interface的所有方法

1
2
3
4
5
6
7
8
type a interface{
a()
b()
}
type b interface{
a
c()
}

反射

Go语言实现了反射,所谓反射就是能检查程序在运行时的状态