> 文章列表 > 3.函数、结构体、包

3.函数、结构体、包

3.函数、结构体、包

一、函数定义和调用

package mainimport ("fmt"
)func test() {fmt.Println("hello world")
}
func main() {test()
}

二、函数的参数

1.单个参数

func test(n int) {fmt.Println("传递进来的参数是", n)
}
func main() {test(10)
}

2.多个参数

func test(x, y int, s string) {fmt.Println(x)fmt.Println(y)fmt.Println(s)}
func main() {test(10, 20, "hello")
}

3.传递不定长参数(切片)

func test(x ...int) {fmt.Println(x)fmt.Println("x的类型为", reflect.TypeOf(x))
}
func main() {test(10, 20, 30, 40)
}

4.定义返回值

在形参括号的后边定义返回参数的类型

func test(x ...int) int {var sum intfor _, v := range x {sum += v}return sum
}
func main() {var sum = test(10, 20, 30, 40)fmt.Println("sum = ", sum)
}

5.函数变量的作用域

变量是先在函数内找,没有在在全局找。

三、匿名函数

var test2 = func() {fmt.Println("hello world")
}

四、高阶函数

1.高阶函数之函数作为参数

package mainimport ("fmt""time"
)func test(f func()) {var start = time.Now().Unix()f()var end = time.Now().Unix()t := end - startfmt.Printf("此程序使用%d秒的时间", t)
}func f1() {time.Sleep(time.Second * 1)
}func main() {test(f1)
}

2.高阶函数之函数作为返回值

这里不在写了,就是python中的装饰器概念。在go中,在一个函数内声明另外一个函数必须使用匿名函数

五、闭包

引用了一个外部的 非全局的自由变量的函数称为闭包函数。闭包主要解决的问题是 "全局变量污染"的问题

实例:
解释:i就是那个 外部的非全局的自由变量
conter的匿名函数就是闭包函数

func getCounter() func() {var i = 0counter := func() {i++fmt.Println(i)}return counter
}
func main() {counter := getCounter()counter()counter()counter()
}

六、结构

go中结构体的概念和C中结构体概念一样。都是多个数据类型的集合

1.定义结构体

type 类型名 struct {字段1 字段1类型字段2 字段2类型…
}

例子:

type student struct {name stringage intgender stringclass string
}

2.实例化

2.1 先声明后赋值

type student struct {name   stringage    intgender stringclass  string
}var s1 student
s1.name = "zhangsan"
s1.age = 20
fmt.Println(s1)

2.2 声明并赋值

这里讲了两种方式

type student struct {name   stringage    intgender stringclass  string
}
var s = student{"zhangsan", 20, "boy", "1班"}
fmt.Println("s = ", s)
var s1 = student{name: "lisi", age: 21}
fmt.Println("s1 = ", s1)

3.结构体的方法接收器

(s stdent)就是和read方法绑定了
read是自定义方法名称

package mainimport "fmt"type student struct {name stringage  int
}func (s student) read() {fmt.Printf("这是%s实例的接收器", s.name)
}func main() {s1 := student{"zhangsan", 10}s1.read()}

4.匿名字段

//正常我们按照格式来这样定义一个结构体
type student struct {name stringage  int
}

4.1 普通匿名字段

匿名字段就是省略字段的名字,直接写类型,如下:
但是不建议这样做

type student struct {stringint
}func main() {var s1 = student{"zhangsan", 20}fmt.Println(s1.string, s1.int)
}

4.2 结构体嵌套的匿名字段

注意:s1是student结构体类型的实例,student中没有name字段,但是AA中有,所有s1可以直接s1.name这样使用

type AA struct {name string
}type student struct {stringintAA
}func main() {var s1 = student{"zhangsan", 20, AA{"lisi"}}fmt.Println(s1.string, s1.int, s1.name)
}

4.3 结构体的继承

结构体的继承就是面向对象中的继承,4.2当中的例子就是继承

七、包管理

go的包管理在
1.11之前使用的是go-path
1.11之后使用的是go-mod

1.包管理要求

1.go的包也是以目录为包,在目录下创建go文件,作为包文件
2.go文件中的函数的"首字母"必须大写。在go中规定 函数要想由外部导入和使用必须大写,首字母小写只能内部使用

2.制作一个包

这里直接使用go-mod模式管理包,不在使用go-path模式

test/
├── api
│   └── mysql.go
└── main.go

mysql.go文件内容如下:
注意:函数首字母必须大写

package api   //这里的包名尽量和目录名称保持一致import "fmt"func Mysql_connect() {fmt.Println("正在连接mysql")
}

2.1 初始化包

在项目下初始化一个包:
格式如下:go mod init 自定义名称

PS E:\\code\\go\\test> go mod init mysite结构如下:
test/
├── api
│   └── mysql.go
├── go.mod
└── main.go

创建完毕后会发现报错

gopls was not able to find modules in your workspace.
When outside of GOPATH, gopls needs to know which modules you are working on.

解决办法:

1.ctrl + ,进入设置选项
2.“扩展” --> “Go”–>“Alternate Tools”–>“在setting.json中设置”
加入

"gopls": {     "experimentalWorkspaceModule": true,
}

完整如下:

{"editor.fontFamily": "Consolas, monospace","explorer.confirmDelete": false,"workbench.colorTheme": "Default Light+","window.zoomLevel": 3,"go.alternateTools": {},"gopls": {     "experimentalWorkspaceModule": true,}
}

重启vscode就可以了

2.2 在main.go中导包

注意:在go中,go会以文件中的package 后边定义的名字为包名,而不是像python那样以文件名称为基准

package mainimport "mysite/api"func main() {//直接调用,vscode会自动导包的路径api.Mysql_connect()
}

将包名从mysql.go中的api改为newapi,编辑器会自动导入成这样.

package mainimport ("fmt"newapi "mysite/api"
)func main() {newapi.Mysql_connect()fmt.Println("hello")
}

3.使用第三方包

//在项目目录下载第三方包
go get 包路径

QQ个性签名网