go包的理解
结论:
- import时指定的字符串,是相对于$GOPATH的目录路径,告诉了go,要去加载这个目录下所有的包文件(不包括子目录中的文件)
- 一个目录中所有的源文件(不包括子目录)代表了单独的一个包,这些源文件内的package关键字指出的包名,必须一致,否则无法被使用
- import指定的加载目录、目录中的源文件名字、源文件内通过package关键字指定的包名。这三者可以不一样。导入后,根据package指定的包名,来使用包中的导出成员。
- 导入两个目录,这两个目录中的源文件内指定的包名,如果出现相同,则导入目录时会失败
- 同一个包,间接或直接被导入多次。这个包只会被初始化一次。如init执行一次,包级别变量的内存只会被分配一次,后续要使用的话,则继续使用上次分配时的值。(这个规律和nodejs也是一致的)这也就是为什么使用mysql时,要导入两个包:
import "database/sql"
import _ "github.com/go-sql-driver/mysql"-
第二个包中引用了第一个包,init函数中对第一个包里的数据进行了一些mysql相关的操作。使后续直接使用第一个包时,能关联得上mysql。
- 导入第二个包仅仅是为了执行里面的init函数,从而影响第一个包的行为。所以第二个包空导入即可
- 当源文件被加载时,文件内的init函数会被自动执行:
- 通过import来加载一个目录时,如果这个目录中有多个源文件,则这些源文件中的init函数都会执行,但文件之间的init函数的执行次序不确定,看go加载文件是的顺序
- 一个源文件内可以定义多个init函数,多个init函数会按顺序从上往下执行。虽然一个文件内可以定义多个init,但是没有这个必要,把逻辑都集中在一个init函数中,效果一样
测试1
$GOPATH目录如下:
├─pkg
└─src
└─app.go
└─m1
└─k1.go
app.go:
package main
import "m1"
func main() {
x1.Show()
}
k1.go:
package x1
import "fmt"
func Show(){
fmt.Println("show call")
}
运行app.go:输出 show call。
测试2
在以上的m1目录中,创建一个文件k2.go
package x2
import "fmt"
func Show(){
fmt.Println("show call")
}
运行app.go提示:app.go:3:8: found packages x1 (k1.go) and x2 (k2.go) in D:\GoPath\src\m1
测试3

k1和k2文件中,都通过package指定包名为x1。app.go中导入这两个目录,运行报错:
.\app.go:4:8: x1 redeclared as imported package name
previous declaration at .\app.go:3:8
.\app.go:7:2: undefined: "m2".FnInK1
解决办法:导入的时候,将冲突的包名,重命名为另一个值即可,如以下k2pkg

测试4

k1.go:
package x1
import "fmt"
var x1Data int = ;
func init(){
fmt.Println("x1 init call")
x1Data = ;
}
func ShowData(){
fmt.Println(x1Data)
}
func SetData(x int){
x1Data = x;
}
k2.go:
package x2 import "m1"
import "fmt" func init(){
fmt.Println("x2 init call")
x1.SetData()
}
app.go:
package main import _ "m2"
import "m1" func main() {
x1.ShowData()
}
> go run app.go
x1 init call
x2 init call
333
go包的理解的更多相关文章
- socket模块粘包现象理解以及解决思路
粘包现象: 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的 ...
- JavaScript-闭包函数(理解)
JavaScript-闭包函数(理解) var foo = function (a) { return function inner () { console.log(a) } } var faa = ...
- GDT,LDT,GDTR,LDTR 详解,包你理解透彻(转)
引自:http://www.techbulo.com/708.html 一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存 ...
- js--闭包的理解
从技术上来讲,在JS中,每个function都是闭包,因为它总是能访问在它外部定义的数据. 当该内部函数在外部函数外被调用,就生成了闭包. 函数内部可以直接读取全局变量. 闭包就是能够读取其他函数内部 ...
- (linux)BSP板级支持包开发理解
1. 概述 嵌入式系统由硬件环境.嵌入式操作系统和应用程序组成,硬件环境是操作系统和应用程序运行的硬件平台,它随应用的不同而有不同的要求.硬件平台的多样性是嵌入式系统的主要特点,如何使嵌入式操作系统在 ...
- 导入项目后下载jar包问题理解
1.导入,然后你下载的jar包,jar下载成功,并不代表你项目里的代码就能用这个jar包了. 你必须还要本地添加进classpath.必须手动添加进类路径 2.总结就是:下载jar包是下载jar包,添 ...
- Java 包的理解与使用
java中的包可以分为两种:内置包.用户自己定义的包.这里介绍的是用户自定义的包. 一.包的使用 1.创建PackageTest.java package com.packtest; public c ...
- 深入探讨 java.lang.ref 包
深入探讨 java.lang.ref 包 本文主要探讨了 java.lang.ref 包的使用方法,以及源码解读.并就该包在不同 JVM 上的表现进行了比较与分析.通过阅读本文,读者可以加深对 jav ...
- tcpdump抓包命令
本文转自 : http://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html http://www.itshouce.com.cn/l ...
随机推荐
- CentOS 7 iptables 开放8080端口
# 安装iptables-services [root@localhost bin]# yum install iptables-services [root@localhost bin]# /bin ...
- Java ping 主机 端口
22:04:08.002 [main] INFO Ping - 目标地址 192.168.1.107 是否可到达:true 22:04:08.006 [main] INFO Ping - 执行命令 p ...
- Eventlet Greenlet
Eventlet是一个用来处理和网络相关的python网络库,而且可以通过协程来实现并发,在eventlet里,把“协程”叫做greenthread. 所谓并发,就是开启了多个greenthread, ...
- boot and loader
boot and loader boot 程序的所有作用 清屏 将光标移到屏幕左上角 显示 Start Boot 提示信息 加载 loader 程序的代码到 0x10000 物理内存地址 将CPU的段 ...
- devExpress GridControl gridView笔记
gridView1.Appearance.EvenRow.BackColor = Color.FromArgb(, , , ); gridView1.Appearance.OddRow.BackCol ...
- D2 前端会议
D2 前端会议 时间 2019年1月6日 图片
- 【踩坑】遇到 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 报错
今天在重做 iblog 客户端时,测试接口情况,发现了 org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...
- java.lang.ClassNotFoundException:org/apache/commons/collections/CursorableLinkedList
明明有 commons-collections.jar 将jar包复制到Tomcat的WEB-INF/lib下就可以了...
- Java笔记--动态代理
Java动态代理 1.概念 代理: 有时我们并不想直接访问对象A,或者不能直接访问对象A.而是通过访问一个中间对象B,让中间对象B去访问A.这种方式就称为代理. 这里的对象A所属的类就为委托类,或者被 ...
- repair table
mysql> show create table lixl;+-------+---------------------------------------------------------- ...