Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.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 &引用;指向接口的指针,而不是“接口”;_Pointers_Go - Fatal编程技术网

Pointers &引用;指向接口的指针,而不是“接口”;

Pointers &引用;指向接口的指针,而不是“接口”;,pointers,go,Pointers,Go,我正在学习Go,并决定重写我最初用Python编写的MQTT编排器。最基本的部分很好: package main import ( "fmt" "time" "os" MQTT "github.com/eclipse/paho.mqtt.golang" log "github.com/sirupsen/logrus" ) // definitions for a switch type Switch struct { topic strin

我正在学习Go,并决定重写我最初用Python编写的MQTT编排器。最基本的部分很好:

package main

import (
    "fmt"
    "time"
    "os"

    MQTT "github.com/eclipse/paho.mqtt.golang"
    log "github.com/sirupsen/logrus"
)

// definitions for a switch

type Switch struct {
    topic string
    state int
}

func allEvents(client MQTT.Client, msg MQTT.Message) {
    log.WithFields(log.Fields{"topic": msg.Topic(), "payload": fmt.Sprintf("%s", msg.Payload())}).Info()
}


func initMQTT() MQTT.Client {
    opts := MQTT.NewClientOptions()
    opts.AddBroker("tcp://mqtt.example.com:1883")
    opts.SetClientID("go-dispatcher")
    opts.SetCleanSession(true)
    client := MQTT.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }
    log.Info("connected to MQTT broker")
    return client
}

func main() {
    // this is that part I want to modify later in the question
    c := initMQTT()
    if token := c.Subscribe("#", 0, allEvents); token.Wait() && token.Error() != nil {
        fmt.Println(token.Error())
        os.Exit(1)
    }

    time.Sleep(100000 * time.Hour)
}
很久以前,我曾在C中使用过指针,我想修改程序,在初始化部分,通过引用传递客户机(更多的是作为一种学习经验,第一个代码对我来说看起来更好)

它无法使用

# command-line-arguments
.\main.go:29:9: cannot use mqtt.NewClient(opts) (type mqtt.Client) as type *mqtt.Client in assignment:
    *mqtt.Client is pointer to interface, not interface
.\main.go:30:21: client.Connect undefined (type *mqtt.Client is pointer to interface, not interface)
按照建议表单,我试图删除
&
*
(一开始是盲目的,说实话),并得到一个运行时错误

time="2018-05-26T21:02:20+02:00" level=info msg="connected to MQTT broker"
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x604486]

goroutine 1 [running]:
main.main()
    D:/Seafile/dev/Go/src/perso/domotique.dispatcher/main.go:39 +0x36

我想既然我定义了
c
,我就可以把它作为一个参考,但显然c-way在这里不是正确的?
(通常在我阅读的示例中)

这是一个常见的误解。因为您已将
c
定义为一个值而不是指针类型,所以在不重新定义它的情况下无法修改它


您传递了它的内存地址这一事实不允许您修改它。这与许多其他语言不同。

正如错误所述,
mqtt.Client
不是
*mqtt.Client
,您不能互换使用它们。您的init接受
*mqtt.Client
但返回
mqtt.Client
,因此这一行
Client=mqtt.NewClient(opts)
是非法的。其次是
接口
类型,使用指向接口类型的指针几乎从来都不是一个好主意。因此,要在Go中练习指针,最好使用普通类型,如结构、字符串、int等。不是接口,也不是很好的候选者。如果您决定坚持使用接口指针,请理解,接口类型的指针值不能直接用于调用接口()的方法但是您已经知道,因为您正在尝试取消对这一行上的指针的引用
*client.Connect()
。然而,由于计算优先级规则在表达式中是不明确的,所以它不是这样做的。为了让编译器明白,您可以使用类似这样的括号,并且,我忘记了,为了修复初始化行,您需要取消引用客户机参数的指针,并将NewClient的结果分配给它<代码>*client=MQTT.NewClient(opts)。。。因此,实际上有两行代码需要修改才能使程序编译:您必须现在和永远忘记“引用”。Go中绝对没有这样的东西,传递指针值不是按引用传递。克服这一点,将指针视为内存地址。“您传递了它的内存地址这一事实并不能使您修改它。”这是不正确的,请参见此处:
time="2018-05-26T21:02:20+02:00" level=info msg="connected to MQTT broker"
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x604486]

goroutine 1 [running]:
main.main()
    D:/Seafile/dev/Go/src/perso/domotique.dispatcher/main.go:39 +0x36