go get 的不再src目錄中_GO語言基礎進階教程:包的使用

Go語言使用包(package)這種語法元素來組織源碼,所有語法可見性均定義在package這個級別,與Java 、python等語言相比,這算不上什么創新,但與C傳統的include相比,則是顯得“先進”了許多。

myblog
├── conf
│   └── app.conf
├── controllers
│   ├── aboutme_controller.go
│   ├── add_article_controller.go
│   ├── album_controller.go
│   ├── base_controller.go
│   ├── default.go
│   ├── delete_article_controller.go
│   ├── exit_controller.go
│   ├── home_controller.go
│   ├── login_controller.go
│   ├── register_controller.go
│   ├── show_article_controller.go
│   ├── tags_controller.go
│   ├── update_article_controller.go
│   └── upload_controller.go
├── main.go
├── models
│   ├── album_model.go
│   ├── article_model.go
│   ├── home_model.go
│   ├── tags_model.go
│   └── user_model.go
├── myblogweb
├── routers
│   └── router.go
├── static
│   ├── css
│   │   ├── blogsheet.css
│   │   └── lib
│   │       ├── highlight.css
│   │       └── login.css
│   ├── img
│   ├── js
│   │   ├── blog.js
│   │   ├── lib
│   │   │   ├── jquery-3.3.1.min.js
│   │   │   └── jquery.url.js
│   │   └── reload.min.js
│   └── upload
│       └── img
│           └── 2018
│               └── 12
│                   └── 11
│                       ├── 1544511378-bee2.png
├── tests
│   └── default_test.go
├── utils
│   ├── myUtils.go
│   └── mysqlUtils.go
└── views├── aboultme.html├── album.html├── block│   ├── home_block.html│   └── nav.html├── home.html├── index.tpl├── login.html├── register.html├── show_article.html├── tags.html└── write_article.html

Go 語言的源碼復用建立在包(package)基礎之上。包通過 package, import, GOPATH 操作完成。

1、 main包

Go 語言的入口 main() 函數所在的包(package)叫 main,main 包想要引用別的代碼,需要import導入!

2、 package

src 目錄是以代碼包的形式組織并保存 Go 源碼文件的。每個代碼包都和 src 目錄下的文件夾一一對應。每個子目錄都是一個代碼包。

代碼包包名和文件目錄名,不要求一致。比如文件目錄叫 hello,但是代碼包包名可以聲明為 “main”,但是同一個目錄下的源碼文件第一行聲明的所屬包,必須一致!

同一個目錄下的所有.go文件的第一行添加 包定義,以標記該文件歸屬的包,演示語法:

package 包名

包需要滿足:

  • 一個目錄下的同級文件歸屬一個包。也就是說,在同一個包下面的所有文件的package名,都是一樣的。
  • 在同一個包下面的文件package名都建議設為是該目錄名,但也可以不是。也就是說,包名可以與其目錄不同名。
  • 包名為 main 的包為應用程序的入口包,其他包不能使用。
在同一個包下面的文件屬于同一個工程文件,不用import包,可以直接使用

包可以嵌套定義,對應的就是嵌套目錄,但包名應該與所在的目錄一致,例如:

// 文件:qf/ruby/tool.go中
package ruby
// 可以被導出的函數
func FuncPublic() {
}
// 不可以被導出的函數
func funcPrivate() {
}

包中,通過標識符首字母是否大寫,來確定是否可以被導出。首字母大寫才可以被導出,視為 public 公共的資源。

3、 import

要引用其他包,可以使用 import 關鍵字,可以單個導入或者批量導入,語法演示:

A:通常導入

// 單個導入
import "package"
// 批量導入
import ("package1""package2")

B:點操作我們有時候會看到如下的方式導入包

import(. "fmt"
) 

這個點操作的含義就是這個包導入之后在你調用這個包的函數時,你可以省略前綴的包名,也就是前面你調

用的fmt.Println("hello world")可以省略的寫成Println("hello world")

C:起別名

別名操作顧名思義我們可以把包命名成另一個我們用起來容易記憶的名字。導入時,可以為包定義別名,語法演示:

import (p1 "package1"p2 "package2")
// 使用時:別名操作,調用包函數時前綴變成了我們的前綴
p1.Method()

D:_操作如果僅僅需要導入包時執行初始化操作,并不需要使用包內的其他函數,常量等資源。則可以在導入包時,匿名導入。

這個操作經常是讓很多人費解的一個操作符,請看下面這個import:

import ("database/sql"_ "github.com/ziutek/mymysql/godrv") 

_操作其實是引入該包,而不直接使用包里面的函數,而是調用了該包里面的init函數。也就是說,使用下劃線作為包的別名,會僅僅執行init()。

導入的包的路徑名,可以是相對路徑也可以是絕對路徑,推薦使用絕對路徑(起始于工程根目錄)。

4、GOPATH環境變量

import導入時,會從GO的安裝目錄(也就是GOROOT環境變量設置的目錄)和GOPATH環境變量設置的目錄中,檢索 src/package 來導入包。如果不存在,則導入失敗。GOROOT,就是GO內置的包所在的位置。GOPATH,就是我們自己定義的包的位置。

通常我們在開發Go項目時,調試或者編譯構建時,需要設置GOPATH指向我們的項目目錄,目錄中的src目錄中的包就可以被導入了。

5、init() 包初始化

下面我們詳細的來介紹一下這兩個函數:init()、main() 是 go 語言中的保留函數。我們可以在源碼中,定義 init() 函數。此函數會在包被導入時執行,例如如果是在 main 中導入包,包中存在 init(),那么 init() 中的代碼會在 main() 函數執行前執行,用于初始化包所需要的特定資料。例如:包源碼:

src/userPackage/tool.go
?
package userPackage
import "fmt"
func init() {fmt.Println("tool init")
}

主函數源碼:

src/main.go
?
package main
import ("userPackage")
func main() {fmt.Println("main run")// 使用userPackageuserPackage.SomeFunc()
}

執行時,會先輸出 "tool init",再輸出 "main run"。

下面我們詳細的來介紹一下init()、main() 這兩個函數。在 go 語言中的區別如下: 相同點:

兩個函數在定義時不能有任何的參數和返回值。該函數只能由 go 程序自動調用,不可以被引用。

不同點:

init 可以應用于任意包中,且可以重復定義多個。main 函數只能用于 main 包中,且只能定義一個。

兩個函數的執行順序:

在 main 包中的 go 文件默認總是會被執行。

對同一個 go 文件的 init( ) 調用順序是從上到下的。

對同一個 package 中的不同文件,將文件名按字符串進行“從小到大”排序,之后順序調用各文件中的init()函數。

對于不同的 package,如果不相互依賴的話,按照 main 包中 import 的順序調用其包中的 init() 函數。

如果 package 存在依賴,調用順序為最后被依賴的最先被初始化,例如:導入順序 main –> A –> B –> C,則初始化順序為 C –> B –> A –> main,一次執行對應的 init 方法。main 包總是被最后一個初始化,因為它總是依賴別的包

避免出現循環 import,例如:A –> B –> C –> A。

一個包被其它多個包 import,但只能被初始化一次

6、管理外部包

go允許import不同代碼庫的代碼。對于import要導入的外部的包,可以使用 go get 命令取下來放到GOPATH對應的目錄中去。

舉個例子,比如說我們想通過go語言連接mysql數據庫,那么需要先下載mysql的數據包,打開終端并輸入以下命令:

localhost:~ ruby$ go get github.com/go-sql-driver/mysql

安裝之后,就可以在gopath目錄的src下,看到對應的文件包目錄:

也就是說,對于go語言來講,其實并不關心你的代碼是內部還是外部的,總之都在GOPATH里,任何import包的路徑都是從GOPATH開始的;唯一的區別,就是內部依賴的包是開發者自己寫的,外部依賴的包是go get下來的。

擴展

我們可以通過go install 來編譯包文件。

我們知道一個非main包在編譯后會生成一個.a文件(在臨時目錄下生成,除非使用go install安裝到$GOROOT或?$GOPATH下,否則你看不到.a),用于后續可執行程序鏈接使用。

比如Go標準庫中的包對應的源碼部分路徑在:$GOROOT/src,而標準庫中包編譯后的.a文件路徑在$GOROOT/pkg/darwin_amd64下。


作者:茹姐

出處:千鋒教育go語言教研部

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534171.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534171.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534171.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python mysql 正則表達式,MySQL之正則表達式(REGEXP)

MySQL中正則表達式通常被用來檢索或替換符合某個模式的文本內容,根據指定的匹配模式匹配文中符合要求的特殊字符串。例如,從一個文件中提取電話號碼,查找一篇文章中重復的單詞或替換用戶輸入的敏感語匯等,這些地方都可以使用正則表…

pyecharts anaconda_Pyecharts安裝使用和繪圖案例

一次偶然的機會,接觸了pyecharts,發現做圖交互效果非常棒,便深究、摸索、入坑。這篇文章主要講述自己在安裝和使用中遇到的問題,解決方法,最后還會有pyecharts中自己比較喜歡的繪圖功能。pyecharts是一款將python與ech…

控制附件的大小 php,wordpress如何修改默認上傳附件限制大小

關于上傳文件大小的限制,有很多有幾種情況,一是服務器上的限制(php.ini)php虛擬主機空間提供商為了保障服務器穩定、都會限制大容量附件上傳,在php.ini文件中做了限制,二是網站程序本身都會有限制大小,wp媒體文件大小默…

如何把密度函數化為標準正態二維分布_概率微課:第三章(22) 二維隨機變量及分布函數定義...

主要內容二維隨機變量及分布函數定義更多系列視頻概率微課:第二章(1) 隨機變量的定義概率微課:第二章(2) 離散型隨機變量概率微課:第二章(3) 兩點分布及伯努利試驗概率微課:第二章(4) 二項分布1概率微課:第二章(5) 二…

php中的緩,php中的緩存機制解釋

php緩存的理解,先列出ob系列函數的作用:ob_start(func) 開啟php緩存,回調函數是對緩存內數據的處理函數ob_gzhandler 作為 ob_start 的回調函數,對數據進行gz壓縮ob_implicit_flush(true/false) 打開或關閉apache緩存&#xff0c…

php 下拉菜單多選get,Jquery實現select二級聯動多選下拉菜單

前言平時雖然也有寫前端,但是對于一些復雜的功能實現仍是一知半解。這次項目需要實現一個多選下拉菜單,并且該菜單要和上級下拉菜單保持聯動。更加麻煩的是,我需要完成以下操作,以省、市二級聯動菜單為例:選擇河北省 &…

idea快捷鍵打開run的窗口_看了上篇文章,你不了解的IDEA操作……

注意作者:卡洛小豆。換種方式寫文章,寫的不好請多多見諒。未經授權,禁止轉載夜,結束了一天的喧囂后安靜下來,伴隨著遠處路燈那微弱的光。風,毫無預兆地席卷整片曠野,撩動人的思緒萬千。那是一個…

oracle查看物化視圖的索引,oracle – 物化視圖中的域索引返回零行

我有Oracle DB的問題 – 在物化視圖上通過CONTAINS()搜索后,域索引返回零行.我看到物化視圖充滿了數據,我還使用過程ctx_ddl.sync_index()進行域索引同步.什么有用:>創建表>插入數據>創建域索引> SYNC DOMAIN INDEX>通過包含找到行 – 返回行什么不起…

arma模型_Eviews經典案例 | 初學者必看!ARMA模型精講

【本期分析師介紹】希音老師,《數據分析學堂》金牌分析師,對eviews的時間序列、ARMA、VAR、VECM、ARCH、GARCH等操作有深入的研究和實戰經驗,累計服務客戶1000。今天邀請希音老師給大家分享eviews的詳細操作步驟。長文預警!可在文末聯系麻瓜學…

oracle活躍用戶,監控數據庫中的活躍用戶及其運行

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓[sql] view plain copy print?set linesize 120 pagesize 66col c1 for a9col c1 heading "OS User"col c2 for a9col c2 heading "Oracle User"col b1 for a9col b1 heading "Unix PID"col b2 for…

c# 路徑下的最近文件夾_C#8.0的兩個有趣的新特性以及gRPC

最近每天忙著跑很多地方,回家就不想動了,沒什么心情寫東西。今天有空,稍微寫一點。下文中:關于C#語法特性的部分需要Visual Studio 2019支持。關于.NET Core的部分需要安裝.NET 3.0 Preview4,低版本或許也可以但我沒實…

alter table add column多個字段_ElementUI表格el-table表頭固定自適應高度解決方案

一、前言ElementUI、iView都以相同的方式提供了表格組件表頭固定的方法,即設置組件的height屬性。表頭固定很重要,就在于當表格數據項很多時,滾動條出現在表格組件內,而不是出現在表格組件外——這樣的優點在于,滾動瀏…

oracle ora 12011,執行oracle中的job報錯:ORA-12011:無法執行作業1

LZ在做一個job執行每天新增一個表的操作時,存儲過程運行沒問題,job也創建成功,但運行job時,卻報錯: ,后又用sys用戶登陸創建了同樣的存儲過程和job,結果可以執行成功。當時就猜測是權限問題。后…

e盤是否具有讀寫權限_輕松搭建MySQL主從復制、讀寫分離(雙機熱備)

主從復制: 當mysql數據庫的數據量太大的時候,查詢數據就很吃力了,無論怎么優化都會產生瓶頸,這時我們需要增加服務器設備來實現分布式數據庫,實現多機熱備份,要想實現多機的熱備,首先要了解主從…

linux運維之道基礎命令,Linux運維之道(7)——Linux管理類命令

(Linux)[系統管理]1. 目錄管理類命令1.1 cd命令格式:cd [-L|[-P [-e]] [-]] [dir]被你忽略的小知識:在這里科普一個小小的知識點,就是關于cd -為什么可以自由的在當前目錄和之前目錄相互切換?其實,在我們的 Shell 的環…

html畫圖代碼_python之matplotlib畫圖教程(2)

各位小表貝,你們的畫圖小老弟又來咯~上一次我們聊到了如何畫離散圖,這一次我們來點復雜的,準備好了么,系好安全帶,準備發車咯~滴滴~我們先來點比較簡單,那種易于上手的。如果現在我知道了兩個點的坐標&…

在linux上面找一個腳本,30個Linux Shell腳本經典案例

在學習Linux運維時,普遍反饋是:Linux Shell是一個很難的知識板塊。雖然大家都認真學,基本的語法也都掌握了,但有需求時,很難直接上手編程,要么寫了很久,要么寫不好!也有很多做運維很…

python圖像識別代碼_用Python進行簡單圖像識別(驗證碼)

這是一個最簡單的圖像識別,將圖片加載后直接利用Python的一個識別引擎進行識別 將圖片中的數字通過 pytesseract.image_to_string(image)識別后將結果存入到本地的txt文件中 #-*-encoding:utf-8-*- import pytesseract from PIL import Image class GetImageDate(ob…

linux 端口添加地址,linux – 綁定,網絡(接口)和多播地址有什么區別?

實際上你在這里混淆了三種方法.第一個是bind,用于將套接字綁定到指定的地址和端口.使用此方法基本上您打開一個udp-port并等待該地址上的此端口的數據.第二個是join-method,用于讓套接字加入指定的多播組.組播組的示例是224.0.0.1 – “所有主機”組播組 – 其針對同一網段上的…

c++ map初始化_Go學習每日一問(18)-map元素查找

每次學習并整理一個Golang的知識點,每天進步一點點。今天學習下go中的一個知識點:map元素查找日省吾身1.下面代碼中 A B 兩處應該怎么修改才能順利編譯?func main() { var m map[string]int //A m["a"] 1 if v : m["b&q…