Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers go-attribute中的引用不';不变_Pointers_Go_Reference_Slice - Fatal编程技术网

Pointers go-attribute中的引用不';不变

Pointers go-attribute中的引用不';不变,pointers,go,reference,slice,Pointers,Go,Reference,Slice,我很难理解参考资料是如何运作的。我想写一个非常简单的内存发布-订阅机制。代码如下: package sockets import ( "fmt" "github.com/gorilla/websocket" ) type hubSingleton struct { Clients map[string][]*websocket.Conn } var instance *hubSingleton func Hub() *hubSingleton { if

我很难理解参考资料是如何运作的。我想写一个非常简单的内存发布-订阅机制。代码如下:

package sockets

import (
    "fmt"

    "github.com/gorilla/websocket"
)

type hubSingleton struct {
    Clients map[string][]*websocket.Conn
}

var instance *hubSingleton

func Hub() *hubSingleton {

    if instance == nil {
        fmt.Println("New instance created")
        instance = &hubSingleton{}
    }
    instance.Clients = make(map[string][]*websocket.Conn, 6)
    return instance
}

func (hub *hubSingleton) Subscribe(channel string, socket *websocket.Conn) error {
    if _, ok := hub.Clients[channel]; !ok {
        hub.Clients[channel] = make([]*websocket.Conn, 0)
    }
    hub.Clients[channel] = append(hub.Clients[channel], socket)

    fmt.Println("Subscribe: ", hub.Clients)
    return nil
}

func (hub *hubSingleton) Publish(channel string, message interface{}) {
    fmt.Println("Publish: ", hub.Clients)

    if _, ok := hub.Clients[channel]; !ok {
        return
    }
    for i := 0; i < len(hub.Clients[channel]); i++ {
        conn := hub.Clients[channel][i]
        conn.WriteJSON(Message{status: "ok", content: message})
    }
}
每次我调用Hub()时,添加到映射的订阅者都会消失。
如何在调用之间保留映射中的更改?

Hub函数在每次调用时创建一个新的客户端映射。将功能更改为:

func Hub() *hubSingleton {
  if instance == nil {
    fmt.Println("New instance created")
    instance = &hubSingleton{}
    instance.Clients = make(map[string][]*websocket.Conn, 6)
  }
  return instance
}
如果对
Hub
的第一次调用来自请求处理程序,那么
实例上就存在数据竞争。使用锁固定座圈:

var (
  instance *hubSingleton
  mu sync.Mutex
)

func Hub() *hubSingleton {
  mu.Lock()
  defer mu.Unlock()
  if instance == nil {
    fmt.Println("New instance created")
    instance = &hubSingleton{}
    instance.Clients = make(map[string][]*websocket.Conn, 6)
  }
  return instance
}
更简单的方法是在使用前初始化实例一次:

var instance *hubSingleton

func newHub() *hubSingleton {
   return &hubSingleton{Clients:  make(map[string][]*websocket.Conn, 6)}
}

func main() {
   instance = newHub()
   ...
}

如果处理程序同时调用
Publish
Subscribe
,则
Publish
Subscribe
中的
Clients
上存在数据争用,
Hub
函数会在每次调用时创建一个新的客户端映射。将功能更改为:

func Hub() *hubSingleton {
  if instance == nil {
    fmt.Println("New instance created")
    instance = &hubSingleton{}
    instance.Clients = make(map[string][]*websocket.Conn, 6)
  }
  return instance
}
如果对
Hub
的第一次调用来自请求处理程序,那么
实例上就存在数据竞争。使用锁固定座圈:

var (
  instance *hubSingleton
  mu sync.Mutex
)

func Hub() *hubSingleton {
  mu.Lock()
  defer mu.Unlock()
  if instance == nil {
    fmt.Println("New instance created")
    instance = &hubSingleton{}
    instance.Clients = make(map[string][]*websocket.Conn, 6)
  }
  return instance
}
更简单的方法是在使用前初始化实例一次:

var instance *hubSingleton

func newHub() *hubSingleton {
   return &hubSingleton{Clients:  make(map[string][]*websocket.Conn, 6)}
}

func main() {
   instance = newHub()
   ...
}

如果处理程序同时调用
Publish
Subscribe
,则
Publish
Subscribe
中的
Clients
上存在数据争用。发布您如何调用此代码的代码。发布您如何调用此代码的代码。