Utiliser le mécanisme d'écoute pour résoudre la référence circulaire du package Golang

introduction

Ce problème apparaît dans le problème rencontré lors de l'écriture des projets, c'est-à-dire la référence circulaire du package. L'introduction du mécanisme Listener peut résoudre ce problème. En fait, cette solution peut également être étendue à d'autres langages.

résoudre

En fait, la description du problème est très simple, c'est-à-dire qu'il existe des références entre les deux packages. Bien entendu, la meilleure solution est de prendre en compte ce problème lors de la conception, afin d'éviter ce problème au stade de la conception, mais tout le monde ne le peut pas L'étape de conception semble si profonde, donc lorsque ce problème survient, nous avons besoin d'un mécanisme pour résoudre ce problème, en fait, c'est un mécanisme de rappel spécial.

package A
testA.go
func LoadServerConfig(filename string, cfg *Connect.ServerConfig) bool{
    
    
....
}

func init(){
    
    
	Connect.RegisterRestServerListener(LoadServerConfig)
}
package B
testB.go

type ServerConfig struct{
    
    
...
}

type ServerListener func(filename string, cfg *ServerConfig) bool

var ServerListeners []ServerListener

func RegisterRestServerListener(l ServerListener) {
    
    
	ServerListeners = append(ServerListeners, l)
}

Nous pouvons clairement voir que le package A contient le ServerConfig dans le package B, et le package B sera à nouveau utilisé LoadServerConfig. A ce moment, une référence circulaire apparaîtra. La solution consiste à en introduire une ServerListeners, initqui est considérée LoadServerConfigcomme un appel de rappel dans la fonction du package A. RegisterRestServerListenerMettez les ServerListeners dans les ServerListeners. Pour le moment, il n'est pas nécessaire d'appeler directement le package B dans le package B. Le rappel dans l' LoadServerConfigappel direct ServerListenersest OK, mais nous devons également introduire le A package où le package B doit être appelé, et importajoutez-le à la fin _, ce qui signifie Exécuter les initfonctions du package afin que les fonctions du package A puissent être liées au package B.

En fait, il existe une autre méthode, qui est la méthode dans [1], mais je pense personnellement qu'elles sont presque les mêmes. Je n'ai pas vraiment compris la signification du pointeur tournant. Je pensais avoir écrit un test simple code pour voir que le virage ne tourne pas, tout peut passer.

package test_cycle_a

import (
"fmt"
"hello/test_cycle_b"
)

func init() {
    
    
	str := "hello world"
	test_cycle_b.Test(str, rocketfunction)
}

func rocketfunction(str string)  {
    
    
	fmt.Println("hello : " ,str)
}
package test_cycle_b

import (
	"fmt"
	"strconv"
	"unsafe"
)

type Callback func(str string)

var Fun Callback

func Test(str string, callback Callback)  {
    
    
	//pointer 转 string
	straddress := &callback
	strPiniter := fmt.Sprintf("%d", unsafe.Pointer(straddress))
	fmt.Println("connection is", strPiniter)

	//string 转 pointer
	intPointer, _ := strconv.ParseInt(strPiniter, 10, 0)
	var pointer *Callback
	pointer = *(**Callback)(unsafe.Pointer(&intPointer))

	(Callback)(*pointer)(str)
	Fun = (Callback)(*pointer)
}
package main

import "hello/test_cycle_b"
import _ "hello/test_cycle_a"


func main(){
    
    
	test_cycle_b.Fun("lizhaolong")
}

ouput:
connection is 824634925080
hello :  hello world
hello :  lizhaolong

Si nous package test_cycle_bremplaçons la fonction Test par la fonction suivante:

func Test(str string, callback Callback)  {
    
    
	Fun = callback
	return
}

Continuez à appeler la mainfonction ci-dessus , nous avons constaté qu'elle pouvait toujours s'exécuter avec succès, en fait, c'est la même chose que la première solution pour le moment.

En fait, il a été mentionné dans [1] d'utiliser la requête HTTP pour le résoudre.Je n'ai pas trouvé le contenu pertinent sur Internet. Mais pour l'instant, la première solution a très bien résolu notre problème. S'il existe d'autres meilleures solutions qui peuvent résoudre ce problème, vous pouvez laisser un message pour en discuter

référence:

  1. Article de blog " L'idée de Golang de résoudre le cycle d'importation n'est pas autorisée "
  2. Hirofumi 《bugfan / mytools

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43705457/article/details/109194901
conseillé
Classement