Pointers &引用;指向接口的指针,而不是“接口”;
我正在学习Go,并决定重写我最初用Python编写的MQTT编排器。最基本的部分很好: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
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