|
@@ -1,6 +1,6 @@
|
|
|
-#B 自定义和外部包的使用,编译,测试,文档和安装
|
|
|
|
|
-#9.5 自定义包和可见性
|
|
|
|
|
|
|
+# 9.5 自定义包和可见性
|
|
|
|
|
|
|
|
|
|
+203
|
|
|
包是Go语言中代码组成和代码编译的主要方式。很多关于它们的基本信息已经在4.2章节中给出,最引人注目的便是可见性。现在我们来看看具体如何来使用自己写的包。在下一节,我们将回顾一些标准库中的包,自定义的包和标准库以外的包。
|
|
包是Go语言中代码组成和代码编译的主要方式。很多关于它们的基本信息已经在4.2章节中给出,最引人注目的便是可见性。现在我们来看看具体如何来使用自己写的包。在下一节,我们将回顾一些标准库中的包,自定义的包和标准库以外的包。
|
|
|
|
|
|
|
|
当写自己包的时候,要使用短小的不含有_(下划线)的小写单词来为文件命名。这里有个简单例子来说明包是如何相互调用以及可见性是如何实现的。
|
|
当写自己包的时候,要使用短小的不含有_(下划线)的小写单词来为文件命名。这里有个简单例子来说明包是如何相互调用以及可见性是如何实现的。
|
|
@@ -12,47 +12,47 @@
|
|
|
package pack1
|
|
package pack1
|
|
|
var Pack1Int int = 42
|
|
var Pack1Int int = 42
|
|
|
var PackFloat = 3.14
|
|
var PackFloat = 3.14
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
func ReturnStr() string {
|
|
func ReturnStr() string {
|
|
|
return "Hello main!"
|
|
return "Hello main!"
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
它包含了一个整型变量PackInt和一个返回字符串的函数ReturnStr。这段程序在运行时不做任何的事情,因为它不包含有一个main函数。
|
|
它包含了一个整型变量PackInt和一个返回字符串的函数ReturnStr。这段程序在运行时不做任何的事情,因为它不包含有一个main函数。
|
|
|
|
|
|
|
|
在主程序pack_test.go中这个包通过声明的方式被导入
|
|
在主程序pack_test.go中这个包通过声明的方式被导入
|
|
|
|
|
|
|
|
- import “./pack1/pack1”
import的一般格式如下:
|
|
|
|
|
|
|
+ import “./pack1/pack1”
import的一般格式如下:
|
|
|
import “包的路径或url地址“ 像 import "github.com/org1/pack1”
|
|
import “包的路径或url地址“ 像 import "github.com/org1/pack1”
|
|
|
|
|
|
|
|
路径是指当前目录的相对路径。
|
|
路径是指当前目录的相对路径。
|
|
|
|
|
|
|
|
示例 9.5 [package_test.go](examples/chapter_9/package_test.go)
|
|
示例 9.5 [package_test.go](examples/chapter_9/package_test.go)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
package main
|
|
package main
|
|
|
import (
|
|
import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"./pack1/pack1"
|
|
"./pack1/pack1"
|
|
|
)
|
|
)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
func main() {
|
|
func main() {
|
|
|
var test1 string
|
|
var test1 string
|
|
|
test1 = pack1.ReturnStr()
|
|
test1 = pack1.ReturnStr()
|
|
|
fmt.Printf("ReturnStr from package1: %s\n", test1)
|
|
fmt.Printf("ReturnStr from package1: %s\n", test1)
|
|
|
fmt.Printf(“Integer from package1: %d\n”, pack1.Pack1Int)
// fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)
|
|
fmt.Printf(“Integer from package1: %d\n”, pack1.Pack1Int)
// fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
输出结果:
|
|
输出结果:
|
|
|
-
ReturnStr from package1: Hello main!
Integer from package1: 42
|
|
|
|
|
-
|
|
|
|
|
|
|
+
ReturnStr from package1: Hello main!
Integer from package1: 42
|
|
|
|
|
+
|
|
|
如果包pack1和我们的程序在统同一路径下,我们可以通过"import ./pack1"这样的方式来引入,但这不被视为一个好的方法。
|
|
如果包pack1和我们的程序在统同一路径下,我们可以通过"import ./pack1"这样的方式来引入,但这不被视为一个好的方法。
|
|
|
fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)这行代码试图访问一个未引用的变量或者函数,甚至没有编译。将会返回一个错误:
|
|
fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)这行代码试图访问一个未引用的变量或者函数,甚至没有编译。将会返回一个错误:
|
|
|
cannot refer to unexported name pack1.pack1Float
|
|
cannot refer to unexported name pack1.pack1Float
|
|
|
-
|
|
|
|
|
-主程序利用的包必须在主程序编写之前被编译。主程序中每个pack1项目都要通过包名来使用使用:pack1.Item。具体使用方法请参见示例4.6和4.7。
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+主程序利用的包必须在主程序编写之前被编译。主程序中每个pack1项目都要通过包名来使用使用:pack1.Item。具体使用方法请参见示例4.6和4.7。
|
|
|
|
|
+
|
|
|
因此,按照惯例子目录和包之间有着密切的联系:为了区分不同包存放在不同的目录,每个包(所有属于这个包中的go文件)都存放在和包名相同的子目录下。
|
|
因此,按照惯例子目录和包之间有着密切的联系:为了区分不同包存放在不同的目录,每个包(所有属于这个包中的go文件)都存放在和包名相同的子目录下。
|
|
|
|
|
|
|
|
Import with . : import . “./pack1”
|
|
Import with . : import . “./pack1”
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
当使用.来做为包的别名时,你可以不通过包名来使用其中的项目。例如:test := ReturnStr()。
|
|
当使用.来做为包的别名时,你可以不通过包名来使用其中的项目。例如:test := ReturnStr()。
|
|
|
|
|
|
|
|
在当前的命名空间导入pack1包,一般是为了具有更好的测试效果。
|
|
在当前的命名空间导入pack1包,一般是为了具有更好的测试效果。
|
|
@@ -75,7 +75,7 @@ pack1包只导入其副作用,只执行了它的init函数并初始化了其
|
|
|
通过以下方式,一次性安装,并导入到你的代码中:
|
|
通过以下方式,一次性安装,并导入到你的代码中:
|
|
|
|
|
|
|
|
import goex “codesite.ext/author/goExample/goex”
|
|
import goex “codesite.ext/author/goExample/goex”
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
因此你项目的路径将成为导入包的网络地址
|
|
因此你项目的路径将成为导入包的网络地址
|
|
|
|
|
|
|
|
在http://golang.org/cmd/goinstall/的go install文档中列出了一些广泛被使用的托管在网络代码仓库的包的导入路径
|
|
在http://golang.org/cmd/goinstall/的go install文档中列出了一些广泛被使用的托管在网络代码仓库的包的导入路径
|
|
@@ -103,7 +103,7 @@ init函数是不能被调用的。
|
|
|
go install(参见9.7章节,从Go1的首选方式)同样复制pack1.a到本地的$GOROOT/pkg的目录中一个以操作系统为名的子目录下。像 import "pack1"代替imort "path to pack1",这样只通过名字就可以将包在程序中导入。
|
|
go install(参见9.7章节,从Go1的首选方式)同样复制pack1.a到本地的$GOROOT/pkg的目录中一个以操作系统为名的子目录下。像 import "pack1"代替imort "path to pack1",这样只通过名字就可以将包在程序中导入。
|
|
|
|
|
|
|
|
如果不可取或不被允许,通过6/8g使用-I选项来编译:
|
|
如果不可取或不被允许,通过6/8g使用-I选项来编译:
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
6g—I map_pack1 package_test.go # where map_pack1 is the map which contains pack1.a
(I选项让编译器查找选项后的目录下是否包含这个包)
|
|
6g—I map_pack1 package_test.go # where map_pack1 is the map which contains pack1.a
(I选项让编译器查找选项后的目录下是否包含这个包)
|
|
|
使用6/8l的-L选项链接:
|
|
使用6/8l的-L选项链接:
|
|
|
6l—L map_pack1 package_test.6
|
|
6l—L map_pack1 package_test.6
|
|
@@ -132,8 +132,6 @@ go install(参见9.7章节,从Go1的首选方式)同样复制pack1.a到本地
|
|
|
|
|
|
|
|
(1)将斐波那契功能放入自己的fibo包中并通过主程序调用它,存储最后输入的值在函数的全局变量。
|
|
(1)将斐波那契功能放入自己的fibo包中并通过主程序调用它,存储最后输入的值在函数的全局变量。
|
|
|
|
|
|
|
|
-(2)扩展fibo包将通过调用斐波那契的时候,操作也作为一个参数。实验"+"和“*”
|
|
|
|
|
|
|
+(2)扩展fibo包将通过调用斐波那契的时候,操作也作为一个参数。实验"+"和“*”
|
|
|
|
|
|
|
|
main_fibo.go / fibonacci.go
|
|
main_fibo.go / fibonacci.go
|
|
|
-
|
|
|
|
|
-
|
|
|