一、go中為什么不允許循環(huán)依賴
目前創(chuàng)新互聯(lián)已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站運營、企業(yè)網(wǎng)站設(shè)計、鉛山網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
二、如何解決循環(huán)依賴
循環(huán)依賴就是A引用B,B又引用A,形成了一個包引用的閉環(huán)。要解決循環(huán)引用,就是打破這個閉環(huán),讓A引用B,B不能引用A??聪旅娴睦樱?/p>
包結(jié)構(gòu)如下:
執(zhí)行main函數(shù)報錯:
報錯的原因是 我們在執(zhí)行bagA.PrintA()的時候,引用了A包,A包又引用了B包,B包又引用了A包,形成了循環(huán)依賴。那我們打破依賴就可以了。
那么該怎么打破呢?
我們發(fā)現(xiàn)A包引用B包,是因為A包需要調(diào)用B包的bagB.GetName()方法;同樣的,B包引用A包,是因為B包需要調(diào)用A包的bagA.GetName()方法。那么,我們有沒有不需要引包就能使B包可以調(diào)用A包的方法呢?
當然是有的。看下面:
我們在B包里定義了一個方法變量AHandler,并且提供了為這個方法變量賦值的方法Register(),然后在A包里的init()方法里,調(diào)用B包的Register()方法,將A包的GetName方法復(fù)賦值給了AHandler變量。 這樣,在B包執(zhí)行方法AHandler是不是就相當于調(diào)用了A包的GetName方法呢?看執(zhí)行結(jié)果:
總結(jié):
上述解決辦法的核心邏輯就是,B包使用一個方法變量來替代A中的方法(來完成B不引用A),A來為該變量賦值(因為A引用B,A可以調(diào)用B的方法來完成賦值)。 解決循環(huán)依賴問題,思想就是打破包的循環(huán)依賴,以不導(dǎo)包的方式調(diào)用其他包的方法。所以,采用接口的形式也可以解決循環(huán)依賴(B定義一個接口,A中你想要調(diào)用的方法實現(xiàn)了該接口,A中完成接口變量賦值,B來調(diào)用接口方法,有時間再補充例子吧)
隊列的概念在 順序隊列 中,而使用循環(huán)隊列的目的主要是規(guī)避假溢出造成的空間浪費,在使用循環(huán)隊列處理假溢出時,主要有三種解決方案
本文提供后兩種解決方案。
順序隊和循環(huán)隊列是一種特殊的線性表,與順序棧類似,都是使用一組地址連續(xù)的存儲單元依次存放自隊頭到隊尾的數(shù)據(jù)元素,同時附設(shè)隊頭(front)和隊尾(rear)兩個指針,但我們要明白一點,這個指針并不是指針變量,而是用來表示數(shù)組當中元素下標的位置。
本文使用切片來完成的循環(huán)隊列,由于一開始使用三個參數(shù)的make關(guān)鍵字創(chuàng)建切片,在輸出的結(jié)果中不包含nil值(看起來很舒服),而且在驗證的過程中發(fā)現(xiàn)使用append()函數(shù)時切片內(nèi)置的cap會發(fā)生變化,在消除了種種障礙后得到了一個四不像的循環(huán)隊列,即設(shè)置的指針是順序隊列的指針,但實際上進行的操作是順序隊列的操作。最后是對make()函數(shù)和append()函數(shù)的一些使用體驗和小結(jié),隊列的應(yīng)用放在鏈隊好了。
官方描述(片段)
即切片是一個抽象層,底層是對數(shù)組的引用。
當我們使用
構(gòu)建出來的切片的每個位置的值都被賦為interface類型的初始值nil,但是nil值也是有大小的。
而使用
來進行初始化時,雖然生成的切片中不包含nil值,但是無法通過設(shè)置的指針變量來完成入隊和出隊的操作,只能使用append()函數(shù)來進行操作
在go語言中,切片是一片連續(xù)的內(nèi)存空間加上長度與容量的標識,比數(shù)組更為常用。使用 append 關(guān)鍵字向切片中追加元素也是常見的切片操作
正是基于此,在使用go語言完成循環(huán)隊列時,首先想到的就是使用make(type, len, cap)關(guān)鍵字方式完成切片初始化,然后使用append()函數(shù)來操作該切片,但這一方式出現(xiàn)了很多問題。在使用append()函數(shù)時,切片的cap可能會發(fā)生變化,用不好就會發(fā)生擴容或收縮。最終造成的結(jié)果是一個四不像的結(jié)果,入隊和出隊操作變得與指針變量無關(guān),失去了作為循環(huán)隊列的意義,用在順序隊列還算合適。
參考博客:
Go語言中的Nil
Golang之nil
Go 語言設(shè)計與實現(xiàn)
本文介紹一些Go語言的基礎(chǔ)語法。
先來看一個簡單的go語言代碼:
go語言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來進一步介紹go的基礎(chǔ)語法。
go語言中格式化輸出可以使用 fmt 和 log 這兩個標準庫,
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問中的fmt包。
log包實現(xiàn)了簡單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來介紹一下go的數(shù)據(jù)類型
下表列出了go語言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲的是一個地址,這個地址存儲最終的值。
常量是在程序編譯時就確定下來的值,程序運行時無法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語言的運算符主要包括算術(shù)運算符、關(guān)系運算符、邏輯運算符、位運算符、賦值運算符以及指針相關(guān)運算符。
算術(shù)運算符:
關(guān)系運算符:
邏輯運算符:
位運算符:
賦值運算符:
指針相關(guān)運算符:
下面介紹一下go語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯(lián)用,這里不做介紹。
if語法格式如下:
if ... else :
else if:
示例代碼:
語法格式:
另外,添加 fallthrough 會強制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過標記退出循環(huán):
--THE END--
分享標題:go語言解決循環(huán)引用問題 go 循環(huán)
網(wǎng)站網(wǎng)址:http://aaarwkj.com/article40/doodsho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、網(wǎng)站策劃、用戶體驗、網(wǎng)站營銷、品牌網(wǎng)站設(shè)計、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)