您好,登錄后才能下訂單哦!
如果代碼太復雜,就可以把代碼寫在多個源碼文件里。或者是其他代碼包中(這個后面講)
下面是程序的主體,但是其中調(diào)用了square()函數(shù),這個函數(shù)并沒有聲明:
// 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()函數(shù)被聲明在了另一個文件中:
// Go36/article03/example01/calc.go
package main
func square(x int) int {
return x * x
}
這里只聲明了一個函數(shù),可以在這個寫更多關(guān)于計算的函數(shù),這樣在同個包里都可以方便的調(diào)用這些函數(shù)使用。
上面的2個文件都要在同一個目錄下,并且需要被聲明為屬于同一個包。
因為示例中都聲明為main包,并且包里也有一個main函數(shù)。所以存在一個命令源碼文件,這樣就可以直接運行起來:
PS H:\Go\src\Go36\article03\example01> go run demo.go calc.go -x 3
3 的平方: 9
PS H:\Go\src\Go36\article03\example01>
上面注意要把所有的文件都寫在命令里。
還可以先構(gòu)建代碼包,在執(zhí)行:
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
}
這里創(chuàng)建了一個子目錄,把文件放到了這個子目錄中,這樣使得它同命令源碼文件不在同一個目錄下了。
并行代碼也做了一些修改:
現(xiàn)在要使用上面的包。導入包的路徑應該是目錄的路徑名稱:
import (
"Go36/article03/example02/lib"
)
如果要構(gòu)建或者安裝這個代碼包,使用的命令應該是下面這樣,還是用目錄名稱:
go install Go36/article03/example02/lib
并且命令成功后,pkg子目錄產(chǎn)生的歸檔文件也是目錄名稱:
pkg\windows_amd64\Go36\article03\example02\lib.a
但是最后調(diào)用的時候需要使用包名稱,命令源碼文件的代碼如下:
// 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)
}
上面調(diào)用程序時使用的lib2.稱為限定符。
結(jié)論:導入路徑使用的是文件所在目錄的路徑。而調(diào)用程序時使用的限定符要與它聲明的包的名稱一致。
為了不在使用代碼包是產(chǎn)生困惑,應該讓聲明的包的名稱與其父目錄的目錄名稱一致。
在這里把函數(shù)名稱的首字母改為大寫的原因是,名稱的首字母為大寫的程序?qū)嶓w才可以被當前包外的代碼引用,否則它就只能被當前包內(nèi)的其他代碼引用。
這涉及了Go語言中對于程序?qū)嶓w訪問權(quán)限的規(guī)則。通過名稱的首字母的大小寫,就把訪問權(quán)限分為了包級私有和公開這兩種。對于包級私有,只有在包內(nèi)部可以訪問。由于我們需要在main包里調(diào)用lib包的函數(shù),只能訪問到公開的部分,所以需要把函數(shù)的首字母大寫。
模塊級私有
上面的訪問權(quán)限都以包的級別進行劃分的。在Go 1.5及后續(xù)版本中,可以通過創(chuàng)建internal代碼包讓一些程序?qū)嶓w僅僅能被當前模塊中的其他代碼引用。這是第三種訪問權(quán)限:模塊級私有。
具體規(guī)則是,internal代碼包中聲明的公開程序?qū)嶓w僅能被該代碼包的直接父包及其子包中的代碼引用。當然,引用前需要先導入這個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包,僅能被直接父包及其子包中的代碼引用。上面如果要在父級里調(diào)用孫級目錄的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>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。