带着问题学go ~~~ 包

什么是包?

就是一种命名空间的体现,或者说就是一个放多个go文件的目录。

不同包之间是隔离的,需要 import 才能访问其它包下的对外成员

同一个包下,作用域是相同的,如下:

main.go 和 calc.go 都在同一个目录下,并且都属于 main 包,所以你会看到,main.go 中可以直接调用 calc.go 中的 add() 函数

假如它们不在同一个包下呢,main.go 又该如何调用 add() ?

注意标红的地方:

  • 函数首字母为什么要大写? 一种约定写法,表示对外开放
  • 引入包,是按模块名称为准的,因为calc包在 helloWorld 模块下。所以是 import “helloWorld/calc”
  • 同一个包下,使用包的成员,就是直接用就行,不用像上面的 calc.Add(1, 2),并且不需要首字母大写。

什么是模块,和包有什么关系?

模块可以理解为一个项目,这个项目可以有多个包组成、

直接看例子:

假设我们有一个聊天服务 imSvr 模块

imSvr/
    - go.mod
        module github.com/junwind/imSvr   // 模块名称
        go 1.18
    - roomSvr   // 包
        - room.go
            package roomSvr
            ...
    - msgSvr    // 包
        - msg.go
            package msgSvr
            ...
    - main.go  // 服务入口
        package main
        import (
            "imSvr/roomSvr"
            "imSvr/msgSvr"
        )
        func main() {
            if roomId == nil {
                roomSvr.CreateRoom()
            } else {
                roomSvr.JoinRoom(roomId)
                if sendMsg != nil {
                    msgSvr.Push(roomId, sendMsg)
                }
            }
        }

如何定义一个包?

直接在文件开头写上 package 包名

一般一个目录就是一个包,包名称一般和目录名称一致,它下面的直属文件都属于这个包(子目录也可能是另一个包),比如:

pveSvr
    pk.go
        package pveSvr
        ...
    worldBossBattle
        battle.go
            package worldBossBattle
            ...

包名不能包含 - 符号

main包是程序的入口包,这种包编译后会得到一个可执行的文件。

如何访问包的成员呢?

1、在同一个包下,因为都在一个作用域下,直接访问成员本身就行。

2、不同包下,需要 import,使用时,还需要带上 包名.成员,比如 fmt.Println()

3、想要让包下的成员能被外部访问,该成员名称的首字母必须大写才行。

来看一个例子:

package demo

type Student struct {  // Student结构体能不能在外部访问呢?
    Name string  // Name字段能不能在外部访问呢?
    class string  // class字段能不能在外部访问呢?
}

大家手动试一下吧。

怎么引用一个包

import importname "module/package"

importname 可以理解为包的别名,默认就是包名,一般不写

为什么要有这个包别名机制呢?

想一想,假如两个包名称刚好相同呢,那么我们使用起来岂不是就冲突了。

import f "fmt"
import (
    test1 test
    test2 test
)

注意:go中,禁止循环引用包,比如 A包中用B包,B包中用A包。

如何匿名引用一个包,它有什么用?

import _ "github.com/go-sql-driver/mysql"

作用就是为了执行这个包中的 init() 函数。

注意:被匿名引入的包中的init()函数会被执行,而且仅执行一次。

init() 函数是干啥的?

先看代码

func init() {   // 没有参数,没有返回值
    fmt.Println("init001")
}

func init() {
    fmt.Println("init002")
}

func main() {
    fmt.Println("main")
}

执行后,会发现,init函数先执行,也就是说在程序真正执行之前,我们可以在init中做一些初始化动作。

引入的包中,init() 的执行顺序

包里面有没有比 init() 更早的声明呢?

有,在全局作用域(函数外)下的声明的变量,常量,函数等等,都是可以直接在init() 中调用的。大家可以自行测试一下。

由此我们会得知,包的执行顺序了:

1、 处理全局的声明

2、执行引入其它包中的init,执行当前包下的init

3、执行当前包下的main

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇