Go36-3-代码包

把代码拆分到多个文件

如果代码太复杂,就可以把代码写在多个源码文件里。或者是其他代码包中(这个后面讲)

代码示例

下面是程序的主体,但是其中调用了square()函数,这个函数并没有声明:

// Go36/article03/example01/demo.go
package main

import (
    "flag"
    "fmt"
)

var x int

func init() {
    flag.IntVar(&x, "x", 0, "计算平方")
}

func main() {
    flag.Parse()
    res := square(x)
    fmt.Println(x, "的平方:", res)
}

上面用到的square()函数被声明在了另一个文件中:

// Go36/article03/example01/calc.go
package main

func square(x int) int {
    return x * x
}

这里只声明了一个函数,可以在这个写更多关于计算的函数,这样在同个包里都可以方便的调用这些函数使用。
上面的2个文件都要在同一个目录下,并且需要被声明为属于同一个包。

执行代码

因为示例中都声明为main包,并且包里也有一个main函数。所以存在一个命令源码文件,这样就可以直接运行起来:

PS H:\Go\src\Go36\article03\example01> go run demo.go calc.go -x 3
3 的平方: 9
PS H:\Go\src\Go36\article03\example01>

上面注意要把所有的文件都写在命令里。
还可以先构建代码包,在执行:

PS H:\Go\src> go build Go36/article03/example01
PS H:\Go\src> .\example01.exe -x 4
4 的平方: 16
PS H:\Go\src>

把代码拆分到多个包

先修改calc.go的路径,并且做一些修改:

// Go36/article03/example02/lib/calc.go
package lib2

func Square(x int) int {
    return x * x
}

这里创建了一个子目录,把文件放到了这个子目录中,这样使得它同命令源码文件不在同一个目录下了。
并行代码也做了一些修改:

  1. 包名变成了lib2,这里故意和目录不是同一个名字
  2. 函数名的首字母变成了大写

包名和目录名不同

现在要使用上面的包。导入包的路径应该是目录的路径名称:

import (
    "Go36/article03/example02/lib"
)

如果要构建或者安装这个代码包,使用的命令应该是下面这样,还是用目录名称:

go install Go36/article03/example02/lib

并且命令成功后,pkg子目录产生的归档文件也是目录名称:

pkg\windows_amd64\Go36\article03\example02\lib.a

但是最后调用的时候需要使用包名称,命令源码文件的代码如下:

// Go36/article03/example02/demo.go
package main

import (
    "flag"
    "fmt"
    "Go36/article03/example02/lib"
)

var x int

func init() {
    flag.IntVar(&x, "x", 0, "计算平方")
}

func main() {
    flag.Parse()
    res := lib2.Square(x)
    fmt.Println(x, "的平方:", res)
}

上面调用程序时使用的lib2.称为限定符。
结论:导入路径使用的是文件所在目录的路径。而调用程序时使用的限定符要与它声明的包的名称一致。
为了不在使用代码包是产生困惑,应该让声明的包的名称与其父目录的目录名称一致。

访问权限

在这里把函数名称的首字母改为大写的原因是,名称的首字母为大写的程序实体才可以被当前包外的代码引用,否则它就只能被当前包内的其他代码引用。
这涉及了Go语言中对于程序实体访问权限的规则。通过名称的首字母的大小写,就把访问权限分为了包级私有和公开这两种。对于包级私有,只有在包内部可以访问。由于我们需要在main包里调用lib包的函数,只能访问到公开的部分,所以需要把函数的首字母大写。

模块级私有
上面的访问权限都以包的级别进行划分的。在Go 1.5及后续版本中,可以通过创建internal代码包让一些程序实体仅仅能被当前模块中的其他代码引用。这是第三种访问权限:模块级私有。
具体规则是,internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。当然,引用前需要先导入这个internal包。对于其他代码包,导入该internal包都是非法的,无法通过编译。
这里的名称必须是internal,示例如下:

// 父级目录 Go36/article03/example03/demo.go
package main

import (
    "flag"
    "Go36/article03/example03/lib"
    //"Go36/article03/example03/lib/internal" // 此行无法通过编译。
)

var x int

func init() {
    flag.IntVar(&x, "x", 0, "计算平方")
}

func main() {
    flag.Parse()
    lib.Cale(x)
    //res := internal.Square(x)
    //lib.Cale(res)
}

// 子级目录 Go36/article03/example03/lib/demo_lib.go
package lib

import (
    "fmt"
    "Go36/article03/example03/lib/internal"
)

func Cale(x int) {
    res := internal.Square(x)
    fmt.Println(x, "的平方:", res)
}

// 孙子目录 Go36/article03/example03/lib/internal/internal.go
package internal

func Square(x int) int {
    return x * x
}

模块级私有的internal包,仅能被直接父包及其子包中的代码引用。上面如果要在父级里调用孙级目录的internal包,就是非法的:

PS H:\Go\src\Go36\article03\example03> go run demo.go -x 7
demo.go:6:2: use of internal package not allowed
PS H:\Go\src\Go36\article03\example03>

原文地址:http://blog.51cto.com/steed/2338070

时间: 2024-11-04 14:55:06

Go36-3-代码包的相关文章

category is in invalid format hint微信第三方平台将第三方提交的代码包提交审核出错

微信第三方平台通过接口https://api.weixin.qq.com/wxa/submit_audit?access_token=TOKEN将第三方提交的代码包提交审核时一直返回错误码85008的错误信息: category is in invalid format hint 查了半天是接口提交数据时json_encode时中文不能编码提交 将向微信的提交代码     $this->https_post($url,json_encode($postData)); 改为     $this->

Meteor 中的代码包有点特殊,分为五种

Meteor 中的代码包有点特殊,分为五种: Meteor 核心代码本身分成多个核心代码包(core package),每个 Meteor 应用中都包含,你基本上不需要花费精力来维护它们 常规 Meteor 代码包称为"isopack",或同构代码包(isomorphic package,意味着它们既能在客户端也能在服务器端工作).第一类代码包例如 accounts-ui 或 appcache 由 Meteor 核心团队维护,与 Meteor 捆绑在一起. 第三方代码包就是其他用户开发

Linux下二进制包和源代码包的区分

主要提供三种格式的mysql包:rpm格式.二进制格式.源码格式:(tar打包,gz压缩) rpm格式: libjpeg-devel-6b-33.x86_64.rpm       #rpm格式很好区分, 二进制包: mysql-3.23.58-pc-linux-i686.tar.gz   #二进制格式的包名字很长,有版本号.适应平台.适应的硬件类型等,格式:mysql-<版本>-<OS>-tar.gz 源码包:    php-5.2.14.tar.gz              

变长随机函数发生器代码包

其实就是一个文件更新了,但是如果是发JAVA文件或者补丁,版本会混乱,我干脆直接上传整个代码包 还是StringRamdomTools.java文件更新了,把原来的固定长度的随机函数发生器改成变长随机函数发生器,在实时编译器中测试这个功能 大概只能够运行15分钟不到的时间,时序就出异常了,固定长度的函数发生器运行了5个小时都没有问题,不知道是什么原因? 至于计算的数值结果是否准确,我就没有认真去检测了,反正写这些代码是为了满足一下我们的好奇心吧....好玩而已.... 这个版本的随机函数发生器也

Linux下二进制包和源代码包

主要提供三种格式的mysql包:rpm格式.二进制格式.源码格式:(tar打包,gz压缩) rpm格式: libjpeg-devel-6b-33.x86_64.rpm       #rpm格式很好区分, 二进制包: mysql-3.23.58-pc-linux-i686.tar.gz   #二进制格式的包名字很长,有版本号.适应平台.适应的硬件类型等,格式:mysql-<版本>-<OS>-tar.gz 源码包:    php-5.2.14.tar.gz              

使用phar上线你的代码包

在我前一阵子写的一篇文章<新版 SegmentFault 重构之系统架构>中,很多人对其中提到的利用phar上线代码比较感兴趣,我就在这边跟大家分享下我目前的做法. 哪些项目适合phar打包上线? 其实这种方法没有什么特别的限制,只有一条,你的程序是单一入口的,对web项目也就是说,所有的http请求都只有一个php文件作为处理方(大多数程序就是index.php). 如果你的程序结构是这样的,那么基本可以无障碍切换到这种上线模式.实际上绝大多数现代的php框架构建的项目都是单一入口的结构了.

rpm管理环境包和代码包

Author: JinDate: 20140610System: CentOS release 6.5 (Final) 06-09-2014c零:问题配置文件问题,不打包使用的配置文件参考配置文件后缀.default 有个不替换操作 %config(noreplace) %{etcdir}/%{configfile} 新的安装为 /usr/local/redis/etc/redis.conf.rpmnew版本号更改: :%s/2.8.7/2.8.10/g 一般软件,游戏代码使用另外的 一.基本流

[PHP插件教程]002.代码包PHP Beautifier的使用

This program reformat and beautify PHP source code files automatically. The program is Open Source and distributed under the terms of PHP Licence. It is written in PHP 5 and has a command line tool. PHP Beautifier是一个用php编写的php代码美化工具. 框架详细的介绍地址:http:/

JWFD代码包开发过程说明

各位: JWFD的代码和工程包在实施的时候,并未与其它公司合作开发,完全是COMSCI自己独立的创作 引擎,算法,数据结构,矩阵这些关键模块都是COMSCI独立开发的成果,其它公司并未参与其中 JWFD开源项目并未和其它企业和公司发生过交易和并购的事件,其它公司也未派遣人员进入COMSCI系统 JWFD项目也未派遣人员进入其它公司合作工作,总之,JWFD开源项目是一个完全独立的私人开源项目 JWFD项目也并未向任何广告公司和媒体投放过广告和宣传题材,也未向外部派遣过任何宣传和技术人员 COMSC

【iOS开展-50】使用它来创建一个新的类的实现代码包,因此,不自觉地练习简单MVC实验,附带动画

接下来说说代码封装最后一个个案. 最后一种情况看:[iOS开展-48]九宫格案例:自己主动布局.字典转模型运用.id和instancetype差别.xib反复视图运用及与nib关系 (1)代码封装的原则是:要保证视图控制器尽量少的接触到其它对象的属性,也就是说,尽量把数据或者属性封装到一个类里面,然后利用类或者对象的方法来调用或者设置数据.而是赤裸裸地把属性都写在视图控制器中. 核心作用在于:降低视图控制器的代码量,把数据和属性的处理封装起来,这样也便于其它视图控制器的使用. 要做到的结果就是例