新聞中心
GO語(yǔ)言(十一):開始使用多模塊工作區(qū)
本教程介紹 Go 中多模塊工作區(qū)的基礎(chǔ)知識(shí)。使用多模塊工作區(qū),您可以告訴 Go 命令您正在同時(shí)在多個(gè)模塊中編寫代碼,并輕松地在這些模塊中構(gòu)建和運(yùn)行代碼。
站在用戶的角度思考問題,與客戶深入溝通,找到達(dá)日網(wǎng)站設(shè)計(jì)與達(dá)日網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋達(dá)日地區(qū)。
在本教程中,您將在共享的多模塊工作區(qū)中創(chuàng)建兩個(gè)模塊,對(duì)這些模塊進(jìn)行更改,并在構(gòu)建中查看這些更改的結(jié)果。
本教程需要 go1.18 或更高版本。使用go.dev/dl中的鏈接確保您已在 Go 1.18 或更高版本中安裝了 Go 。
首先,為您要編寫的代碼創(chuàng)建一個(gè)模塊。
1、打開命令提示符并切換到您的主目錄。
在 Linux 或 Mac 上:
在 Windows 上:
2、在命令提示符下,為您的代碼創(chuàng)建一個(gè)名為工作區(qū)的目錄。
3、初始化模塊
我們的示例將創(chuàng)建一個(gè)hello依賴于 golang.org/x/example 模塊的新模塊。
創(chuàng)建你好模塊:
使用 . 添加對(duì) golang.org/x/example 模塊的依賴項(xiàng)go get。
在 hello 目錄下創(chuàng)建 hello.go,內(nèi)容如下:
現(xiàn)在,運(yùn)行 hello 程序:
在這一步中,我們將創(chuàng)建一個(gè)go.work文件來(lái)指定模塊的工作區(qū)。
在workspace目錄中,運(yùn)行:
該go work init命令告訴為包含目錄中模塊的工作空間go創(chuàng)建一個(gè)文件 。go.work./hello
該go命令生成一個(gè)go.work如下所示的文件:
該go.work文件的語(yǔ)法與go.mod相同。
該go指令告訴 Go 應(yīng)該使用哪個(gè)版本的 Go 來(lái)解釋文件。它類似于文件中的go指令go.mod 。
該use指令告訴 Go在進(jìn)行構(gòu)建時(shí)hello目錄中的模塊應(yīng)該是主模塊。
所以在模塊的任何子目錄中workspace都會(huì)被激活。
2、運(yùn)行工作區(qū)目錄下的程序
在workspace目錄中,運(yùn)行:
Go 命令包括工作區(qū)中的所有模塊作為主模塊。這允許我們?cè)谀K中引用一個(gè)包,即使在模塊之外。在模塊或工作區(qū)之外運(yùn)行g(shù)o run命令會(huì)導(dǎo)致錯(cuò)誤,因?yàn)樵揼o命令不知道要使用哪些模塊。
接下來(lái),我們將golang.org/x/example模塊的本地副本添加到工作區(qū)。然后,我們將向stringutil包中添加一個(gè)新函數(shù),我們可以使用它來(lái)代替Reverse.
在這一步中,我們將下載包含該模塊的 Git 存儲(chǔ)庫(kù)的副本golang.org/x/example,將其添加到工作區(qū),然后向其中添加一個(gè)我們將從 hello 程序中使用的新函數(shù)。
1、克隆存儲(chǔ)庫(kù)
在工作區(qū)目錄中,運(yùn)行g(shù)it命令來(lái)克隆存儲(chǔ)庫(kù):
2、將模塊添加到工作區(qū)
該go work use命令將一個(gè)新模塊添加到 go.work 文件中。它現(xiàn)在看起來(lái)像這樣:
該模塊現(xiàn)在包括example.com/hello模塊和 `golang.org/x/example 模塊。
這將允許我們使用我們將在模塊副本中編寫的新代碼,而不是使用命令stringutil下載的模塊緩存中的模塊版本。
3、添加新功能。
我們將向golang.org/x/example/stringutil包中添加一個(gè)新函數(shù)以將字符串大寫。
將新文件夾添加到workspace/example/stringutil包含以下內(nèi)容的目錄:
4、修改hello程序以使用該功能。
修改workspace/hello/hello.go的內(nèi)容以包含以下內(nèi)容:
從工作區(qū)目錄,運(yùn)行
Go 命令在go.work文件指定的hello目錄中查找命令行中指定的example.com/hello模塊 ,同樣使用go.work文件解析導(dǎo)入golang.org/x/example。
go.work可以用來(lái)代替添加replace 指令以跨多個(gè)模塊工作。
由于這兩個(gè)模塊在同一個(gè)工作區(qū)中,因此很容易在一個(gè)模塊中進(jìn)行更改并在另一個(gè)模塊中使用它。
現(xiàn)在,要正確發(fā)布這些模塊,我們需要發(fā)布golang.org/x/example 模塊,例如在v0.1.0. 這通常通過在模塊的版本控制存儲(chǔ)庫(kù)上標(biāo)記提交來(lái)完成。發(fā)布完成后,我們可以增加對(duì) golang.org/x/example模塊的要求hello/go.mod:
這樣,該go命令可以正確解析工作區(qū)之外的模塊。
Go語(yǔ)言設(shè)計(jì)與實(shí)現(xiàn)(上)
基本設(shè)計(jì)思路:
類型轉(zhuǎn)換、類型斷言、動(dòng)態(tài)派發(fā)。iface,eface。
反射對(duì)象具有的方法:
編譯優(yōu)化:
內(nèi)部實(shí)現(xiàn):
實(shí)現(xiàn) Context 接口有以下幾個(gè)類型(空實(shí)現(xiàn)就忽略了):
互斥鎖的控制邏輯:
設(shè)計(jì)思路:
(以上為寫被讀阻塞,下面是讀被寫阻塞)
總結(jié),讀寫鎖的設(shè)計(jì)還是非常巧妙的:
設(shè)計(jì)思路:
WaitGroup 有三個(gè)暴露的函數(shù):
部件:
設(shè)計(jì)思路:
結(jié)構(gòu):
Once 只暴露了一個(gè)方法:
實(shí)現(xiàn):
三個(gè)關(guān)鍵點(diǎn):
細(xì)節(jié):
讓多協(xié)程任務(wù)的開始執(zhí)行時(shí)間可控(按順序或歸一)。(Context 是控制結(jié)束時(shí)間)
設(shè)計(jì)思路: 通過一個(gè)鎖和內(nèi)置的 notifyList 隊(duì)列實(shí)現(xiàn),Wait() 會(huì)生成票據(jù),并將等待協(xié)程信息加入鏈表中,等待控制協(xié)程中發(fā)送信號(hào)通知一個(gè)(Signal())或所有(Boardcast())等待者(內(nèi)部實(shí)現(xiàn)是通過票據(jù)通知的)來(lái)控制協(xié)程解除阻塞。
暴露四個(gè)函數(shù):
實(shí)現(xiàn)細(xì)節(jié):
部件:
包: golang.org/x/sync/errgroup
作用:開啟 func() error 函數(shù)簽名的協(xié)程,在同 Group 下協(xié)程并發(fā)執(zhí)行過程并收集首次 err 錯(cuò)誤。通過 Context 的傳入,還可以控制在首次 err 出現(xiàn)時(shí)就終止組內(nèi)各協(xié)程。
設(shè)計(jì)思路:
結(jié)構(gòu):
暴露的方法:
實(shí)現(xiàn)細(xì)節(jié):
注意問題:
包: "golang.org/x/sync/semaphore"
作用:排隊(duì)借資源(如錢,有借有還)的一種場(chǎng)景。此包相當(dāng)于對(duì)底層信號(hào)量的一種暴露。
設(shè)計(jì)思路:有一定數(shù)量的資源 Weight,每一個(gè) waiter 攜帶一個(gè) channel 和要借的數(shù)量 n。通過隊(duì)列排隊(duì)執(zhí)行借貸。
結(jié)構(gòu):
暴露方法:
細(xì)節(jié):
部件:
細(xì)節(jié):
包: "golang.org/x/sync/singleflight"
作用:防擊穿。瞬時(shí)的相同請(qǐng)求只調(diào)用一次,response 被所有相同請(qǐng)求共享。
設(shè)計(jì)思路:按請(qǐng)求的 key 分組(一個(gè) *call 是一個(gè)組,用 map 映射存儲(chǔ)組),每個(gè)組只進(jìn)行一次訪問,組內(nèi)每個(gè)協(xié)程會(huì)獲得對(duì)應(yīng)結(jié)果的一個(gè)拷貝。
結(jié)構(gòu):
邏輯:
細(xì)節(jié):
部件:
如有錯(cuò)誤,請(qǐng)批評(píng)指正。
如何用go語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)中的隊(duì)列數(shù)據(jù)類型
你的代碼是想把front到rear的值全部輸出
但是你下面的操作自己檢查一下沒有改變front的值,也沒有改變r(jià)ear的值,所以front!=rear是死循環(huán)
如果好一點(diǎn)的話
void printQueue(LinkQueue *Q)/*依次輸出隊(duì)列*/
{
if(Q-front==Q-rear)
{
printf("隊(duì)列為空");
exit(1);
}
while(Q-front!=Q-rear)/*老師告訴我說是這里的while是死循環(huán),為什么是死循環(huán)呢,不是很懂,請(qǐng)細(xì)說。請(qǐng)幫我改為正確的代碼,謝謝。*/
{
printf("%d, ", Q-front-data);
Q-front=Q-front-next;
}
//exit(0);
}試試可不可以,不行再追問
單向散列函數(shù)(go語(yǔ)言實(shí)踐)
單向散列函數(shù)(one-wayfunction)有一個(gè)輸入和一個(gè)輸出,其中輸入稱為消息(message),輸出稱為散列值 (hashvalue)。單向散列函數(shù)可以根據(jù)消息的內(nèi)容計(jì)算出散列值,而散列值就可以被用來(lái)檢查消息的完整性。
這里的消息不一定是人類能夠讀懂的文字,也可以是圖像文件或者聲音文件。單向散列函數(shù)不需要知道消息實(shí)
際代表的含義。無(wú)論任何消息,單向散列函數(shù)都會(huì)將它作為單純的比特序列來(lái)處理,即根據(jù)比特序列計(jì)算出散
列值。
散列值的長(zhǎng)度和消息的長(zhǎng)度無(wú)關(guān)。無(wú)論消息是1比特,還是100MB,甚至是IOOGB,單向散列函數(shù)都會(huì)計(jì)算出固 定長(zhǎng)度的散列值。以SHA-I單向散列函數(shù)為例,它所計(jì)算出的散列值的長(zhǎng)度永遠(yuǎn)是160比特(20字節(jié))。
單向散列函數(shù)的相關(guān)術(shù)語(yǔ)有很多變體,不同參考資料中所使用的術(shù)語(yǔ)也不同,下面我們就介紹其中的兒個(gè)。 單向散列函數(shù)也稱為 消息摘要函數(shù)(message digest function) 、 哈希函數(shù) 或者 雜湊函數(shù) 。 輸入單向散列函數(shù)的消息也稱為 原像 (pre-image) 。
單向散列函數(shù)輸出的散列值也稱為 消息摘要 (message digest)或者 指紋 (fingerprint)。 完整性 也稱為一致性。
MD4是由Rivest于1990年設(shè)計(jì)的單向散列函數(shù),能夠產(chǎn)生128比特的散列值(RFC1186,修訂版RFC1320)。不 過,隨著Dobbertin提出尋找MD4散列碰撞的方法,因此現(xiàn)在它已經(jīng)不安全了。
MD5是由Rwest于1991年設(shè)計(jì)的單項(xiàng)散列函數(shù),能夠產(chǎn)生128比特的散列值(RFC1321)。
MD5的強(qiáng)抗碰撞性已經(jīng)被攻破,也就是說,現(xiàn)在已經(jīng)能夠產(chǎn)生具備相同散列值的兩條不同的消息,因此它也已
經(jīng)不安全了。
MD4和MD5中的MD是消息摘要(Message Digest)的縮寫。
SHA-1是由NIST(NationalInstituteOfStandardsandTechnology,美國(guó)國(guó)家標(biāo)準(zhǔn)技術(shù)研究所)設(shè)計(jì)的一種能夠產(chǎn)生 160比特的散列值的單向散列函數(shù)。1993年被作為美國(guó)聯(lián)邦信息處理標(biāo)準(zhǔn)規(guī)格(FIPS PUB 180)發(fā)布的是 SHA,1995年發(fā)布的修訂版FIPS PUB 180-1稱為SHA-1。
SHA-1的消息長(zhǎng)度存在上限,但這個(gè)值接近于2^64比特,是個(gè)非常巨大的數(shù)值,因此在實(shí)際應(yīng)用中沒有問題。
SHA-256、SHA-384和SHA-512都是由NIST設(shè)計(jì)的單向散列函數(shù),它們的散列值長(zhǎng)度分別為256比特、384比特和
512比特。這些單向散列函數(shù)合起來(lái)統(tǒng)稱SHA-2,它們的消息長(zhǎng)度也存在上限(SHA-256的上限接近于 2^64 比特,
SHA-384 和 SHA-512的上限接近于 2^128 比特)。這些單向散列函數(shù)是于2002年和 SHA-1 一起作為 FIPS PUB 180-2 發(fā)布的 SHA-1 的強(qiáng)抗碰撞性已于2005年被攻破, 也就是說,現(xiàn)在已經(jīng)能夠產(chǎn)生具備相同散列值的兩條不同的消 息。不過,SHA-2還尚未被攻破。
Go語(yǔ)言基礎(chǔ)語(yǔ)法(一)
本文介紹一些Go語(yǔ)言的基礎(chǔ)語(yǔ)法。
先來(lái)看一個(gè)簡(jiǎn)單的go語(yǔ)言代碼:
go語(yǔ)言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來(lái)進(jìn)一步介紹go的基礎(chǔ)語(yǔ)法。
go語(yǔ)言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問中的fmt包。
log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來(lái)介紹一下go的數(shù)據(jù)類型
下表列出了go語(yǔ)言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。
常量是在程序編譯時(shí)就確定下來(lái)的值,程序運(yùn)行時(shí)無(wú)法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語(yǔ)言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。
算術(shù)運(yùn)算符:
關(guān)系運(yùn)算符:
邏輯運(yùn)算符:
位運(yùn)算符:
賦值運(yùn)算符:
指針相關(guān)運(yùn)算符:
下面介紹一下go語(yǔ)言中的if語(yǔ)句和switch語(yǔ)句。另外還有一種控制語(yǔ)句叫select語(yǔ)句,通常與通道聯(lián)用,這里不做介紹。
if語(yǔ)法格式如下:
if ... else :
else if:
示例代碼:
語(yǔ)法格式:
另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語(yǔ)句,不管下一條case語(yǔ)句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語(yǔ)句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過標(biāo)記退出循環(huán):
--THE END--
網(wǎng)頁(yè)標(biāo)題:go語(yǔ)言實(shí)現(xiàn)單列模式,go語(yǔ)言隊(duì)列
網(wǎng)站地址:http://fisionsoft.com.cn/article/dscedid.html