最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang包循環(huán)引用的幾種解決方案總結(jié)

 更新時間:2022年09月19日 09:03:52   作者:云滿筆記  
golang有包循環(huán)引用問題,用過的應(yīng)該都知道,下面這篇文章主要給大家介紹了關(guān)于golang包循環(huán)引用的幾種解決方案,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

1. golang 包循環(huán)引用的幾種解決方案

1.1. 前言

golang 為了加速編譯, 不允許包循環(huán)引用。通常來說, 只要你的包規(guī)劃得好, 嚴格規(guī)范單向調(diào)用鏈 (如控制層 -> 業(yè)務(wù)層 ->數(shù)據(jù)層), 一般不會出現(xiàn)包循環(huán)引用問題。當(dāng)然現(xiàn)實業(yè)務(wù)往往不會這么理想, 同層級之間的不同包經(jīng)常需要互相引用, 下面我就分享幾種解決包循環(huán)引用的方案。

1.2. 新建公共接口包(父包), 將需要循環(huán)調(diào)用的函數(shù)或方法抽象為接口

package_i

package package_i
 
type PackageAInterface interface {
	PrintA()
}
 
type PackageBInterface interface {
	PrintB()
}

package_a

package package_a
 
import (
	"cycle/package_i"
	"fmt"
)
 
type PackageA struct {
	B package_i.PackageBInterface
}
 
func (a PackageA) PrintA() {
	fmt.Println("I'm a!")
}
 
func (a PackageA) PrintAll() {
	a.PrintA()
	a.B.PrintB()
}

package_b

package package_b
 
import (
	"cycle/package_i"
	"fmt"
)
 
type PackageB struct {
	A package_i.PackageAInterface
}
 
func (b PackageB) PrintB() {
	fmt.Println("I'm b!")
}
 
func (b PackageB) PrintAll() {
	b.PrintB()
	b.A.PrintA()
}

main

package main
 
import (
	"cycle/package_a"
	"cycle/package_b"
)
 
func main() {
	a := new(package_a.PackageA)
	b := new(package_b.PackageB)
        a.B = b
        b.A = a
	a.PrintAll()
	b.PrintAll()
}

1.3. 新建公共組合包(子包), 在組合包中組合調(diào)用

package_c

package package_c
 
import (
	"cycle/package_a"
	"cycle/package_b"
)
 
type CombileAB struct {
	A *package_a.PackageA
	B *package_b.PackageB
}
 
func (c CombileAB) PrintAll() {
	c.A.PrintA()
	c.B.PrintB()
}

main

package main
 
import (
	"cycle/package_a"
	"cycle/package_b"
	"cycle/package_c"
)
 
func main() {
	a := new(package_a.PackageA)
	b := new(package_b.PackageB)
	c := new(package_c.CombileAB)
	c.A = a
	c.B = b
	c.PrintAll()
}

1.4. 全局存儲需要相互依賴的函數(shù), 通過關(guān)鍵字進行調(diào)用

callback_mgr

package callback_mgr
 
import (
	"fmt"
	"reflect"
)
 
var callBackMap map[string]interface{}
 
func init() {
	callBackMap = make(map[string]interface{})
}
 
func RegisterCallBack(key string, callBack interface{}) {
	callBackMap[key] = callBack
}
 
func CallBackFunc(key string, args ...interface{}) []interface{} {
	if callBack, ok := callBackMap[key]; ok {
		in := make([]reflect.Value, len(args))
		for i, arg := range args {
			in[i] = reflect.ValueOf(arg)
		}
		outList := reflect.ValueOf(callBack).Call(in)
		result := make([]interface{}, len(outList))
		for i, out := range outList {
			result[i] = out.Interface()
		}
		return result
	} else {
		panic(fmt.Errorf("callBack(%s) not found", key))
	}
}

package_a

package package_a
 
import (
	"cycle/callback_mgr"
	"fmt"
)
 
func init() {
	callback_mgr.RegisterCallBack("getA", new(PackageA).GetA)
}
 
type PackageA struct {
}
 
func (a PackageA) GetA() string {
	return "I'm a!"
}
 
func (a PackageA) PrintAll() {
	fmt.Println(a.GetA())
	fmt.Println(callback_mgr.CallBackFunc("getB")[0].(string))
}

package_b

package package_b
 
import (
	"cycle/callback_mgr"
	"fmt"
)
 
func init() {
	callback_mgr.RegisterCallBack("getB", new(PackageB).GetB)
}
 
type PackageB struct {
}
 
func (b PackageB) GetB() string {
	return "I'm b!"
}
 
func (b PackageB) PrintAll() {
	fmt.Println(b.GetB())
	fmt.Println(callback_mgr.CallBackFunc("getA")[0].(string))
}

main

package main
 
import (
	"cycle/package_a"
	"cycle/package_b"
)
 
func main() {
	a := new(package_a.PackageA)
	b := new(package_b.PackageB)
	a.PrintAll()
	b.PrintAll()
}

1.5. 不需要回調(diào)結(jié)果的可以通過事件總線 (eventBus) 解耦

eventBus

package eventBus
 
import (
	"github.com/asaskevich/EventBus"
)
 
var globalEventBus EventBus.Bus
 
func init() {
	globalEventBus = EventBus.New()
}
 
func Subscribe(topic string, fn interface{}) error {
	return globalEventBus.Subscribe(topic, fn)
}
 
func SubscribeAsync(topic string, fn interface{}, transactional bool) error {
	return globalEventBus.SubscribeAsync(topic, fn, transactional)
}
 
func Publish(topic string, args ...interface{}) {
	globalEventBus.Publish(topic, args...)
}

package_a

package package_a
 
import (
	"cycle/eventBus"
	"fmt"
)
 
func init() {
	eventBus.Subscribe("PrintA", new(PackageA).PrintA)
}
 
type PackageA struct {
}
 
func (a PackageA) PrintA() {
	fmt.Println("I'm a!")
}
 
func (a PackageA) PrintAll() {
	a.PrintA()
	eventBus.Publish("PrintB")
}

package_b

package package_b
 
import (
	"cycle/eventBus"
	"fmt"
)
 
func init() {
	eventBus.Subscribe("PrintB", new(PackageB).PrintB)
}
 
type PackageB struct {
}
 
func (b PackageB) PrintB() {
	fmt.Println("I'm b!")
}
 
func (b PackageB) PrintAll() {
	b.PrintB()
	eventBus.Publish("PrintA")
}

總結(jié)

到此這篇關(guān)于golang包循環(huán)引用的幾種解決方案的文章就介紹到這了,更多相關(guān)golang包循環(huán)引用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • 使用GORM將PostgreSQL集成到Go框架中

    使用GORM將PostgreSQL集成到Go框架中

    在go中集成postgresql需使用gorm orm,步驟如下:安裝go和postgresql,安裝 gorm:go get -u gorm.io/gorm,配置數(shù)據(jù)庫連接字符串,定義模型類,遷移數(shù)據(jù)庫架構(gòu),使用 gorm 進行增刪改查操作,本指南將介紹如何使用 GORM(一個廣受歡迎的 ORM),將PostgreSQL集成到你的Go應(yīng)用中
    2024-08-08
  • 一文帶你搞懂Golang依賴注入的設(shè)計與實現(xiàn)

    一文帶你搞懂Golang依賴注入的設(shè)計與實現(xiàn)

    在現(xiàn)代的 web 框架里面,基本都有實現(xiàn)了依賴注入的功能,可以讓我們很方便地對應(yīng)用的依賴進行管理。今天我們來看看 go 里面實現(xiàn)依賴注入的一種方式,感興趣的可以了解一下
    2023-01-01
  • 淺析Golang中make和new的用法區(qū)別

    淺析Golang中make和new的用法區(qū)別

    在Go語言中,有兩個比較雷同的內(nèi)置函數(shù),分別是new和make方法,二者都可以用來分配內(nèi)存,那他們有什么區(qū)別呢?下面就跟隨小編一起來學(xué)習(xí)一下吧
    2024-02-02
  • Go語言中http和mysql的實現(xiàn)代碼

    Go語言中http和mysql的實現(xiàn)代碼

    本文通過實例代碼給大家介紹了Go語言中http和mysql的實現(xiàn)代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-11-11
  • Go語言單元測試模擬服務(wù)請求和接口返回

    Go語言單元測試模擬服務(wù)請求和接口返回

    這篇文章主要為大家介紹了Go語言單元測試模擬服務(wù)請求和接口返回示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Golang import 導(dǎo)入包語法及一些特殊用法詳解

    Golang import 導(dǎo)入包語法及一些特殊用法詳解

    這篇文章主要介紹了Golang import 導(dǎo)入包語法及一些特殊用法,需要的朋友可以參考下
    2020-02-02
  • Golang 如何解析和生成json

    Golang 如何解析和生成json

    這篇文章主要介紹了Golang 如何解析和生成json,幫助大家更好的理解和學(xué)習(xí)golang,感興趣的朋友可以了解下
    2020-09-09
  • windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    這篇文章主要介紹了在windows下使用vscode搭建golang環(huán)境并進行調(diào)試,主要包括安裝方法及環(huán)境變量配置技巧,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • GoLang 中的隨機數(shù)的示例代碼

    GoLang 中的隨機數(shù)的示例代碼

    本篇文章主要介紹了GoLang 中的隨機數(shù)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Golang實現(xiàn)可重入鎖的示例代碼

    Golang實現(xiàn)可重入鎖的示例代碼

    可重入鎖指的是同一個線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然能獲取該鎖的代碼,在同一個線程在外層方法獲取鎖的時候,在進入內(nèi)層方法會自動獲取鎖。本文將用Golang實現(xiàn)可重入鎖,需要的可以參考一下
    2022-05-05

最新評論

泰兴市| 普洱| 库伦旗| 宜宾县| 界首市| 吕梁市| 凤翔县| 弥渡县| 丹东市| 晋江市| 平湖市| 突泉县| 齐河县| 岳西县| 白朗县| 福清市| 广德县| 兴化市| 右玉县| 革吉县| 新野县| 阿勒泰市| 株洲市| 惠安县| 西丰县| 平利县| 台中县| 浪卡子县| 金坛市| 临夏县| 安西县| 晋宁县| 公主岭市| 普定县| 扎兰屯市| 长丰县| 定襄县| 洛扎县| 太康县| 二手房| 突泉县|