Structs in go and working with pointers

huangapple go评论73阅读模式
英文:

Structs in go and working with pointers

问题

我正在尝试编写我的第一个Go程序,这是一个非常简单的IRC机器人。

我已经完成了连接等部分,但是对于结构体和指针等内容感到困惑。对于使用类的语言来说,结构体对我来说是新的。

我有这个结构体和它的构造函数:

type Bot struct {
    server  string
    port    string
    nick    string
    channel string
    pass    string
    conn    net.Conn
}

// NewBot 主配置
func NewBot() *Bot {
    return &Bot{
        server:  "irc.twitch.tv",
        port:    "6667",
        nick:    "username",
        channel: "#channel",
        pass:    "password123",
        conn:    nil,
    }
}

我的Connect()方法如下:

func (bot *Bot) Connect() (conn net.Conn, err error) {
    ircbot := NewBot()
    conn, err = net.Dial("tcp", bot.server+":"+bot.port)
    // irc连接...
    return bot.conn, nil
}

这一切都很好,我遇到的问题是与我的结构体中的另一个名为Message的方法有关。它只是用于发送消息。代码如下:

// Message 用于发送消息
func (bot *Bot) Message(message string) {
    if message == "" {
        return
    }
    fmt.Printf("Bot: " + message + "\n")
    fmt.Fprintf(bot.conn, "PRIVMSG "+bot.channel+":"+message+"\r\n")
}

每次我尝试使用这个函数时,都会出现以下错误并导致程序崩溃:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x463d73]

我不确定如何正确使用&*符号来实现我想要做的事情。

我以为goroutine是用于多线程的,通过使用"go [做某事]"来实现,但是我没有在任何地方使用它。

编辑:
解决方案

谢谢,我找到了解决方案!对于那些感兴趣的人:
在调用Message()函数的地方,我创建了一个新的Bot实例,导致conn为空。

这是重要的部分,我愚蠢地没有在这里发布。handle()甚至不是Bot的一个方法,这更加愚蠢。

func handle(line string) {
    ircbot := NewBot();
    // 获取用户名、消息等...
    ircbot.CmdInterpreter(username[1], usermessage)
}

这是正确的方式:

func (bot *Bot) handle(line string) {
    // 获取用户名、消息等...
    bot.CmdInterpreter(username[1], usermessage)
}
英文:

I am trying my hand on my first go program which is supposed to be a very simple IRC bot.

I have the part of the connections etc done but I am confused with structs and pointers such. The structs are new to me coming from languages that use classes.

I have this struct and the constructor for it:

type Bot struct {
	server  string
	port    string
	nick    string
	channel string
	pass    string
	conn    net.Conn
}

// NewBot main config
func NewBot() *Bot {
	return &Bot{
		server:  "irc.twitch.tv",
		port:    "6667",
		nick:    "username",
		channel: "#channel",
		pass:    "password123",
		conn:    nil,
	}
}

My connect() method looks like this

func (bot *Bot) Connect() (conn net.Conn, err error) {
	ircbot := NewBot()
	conn, err = net.Dial("tcp", bot.server+":"+bot.port)
	// irc connection...
    return bot.conn, nil
}

Everything of that works fine the problem I am having is with another method to my struct named Message. It's just supposed to send a message. Looks like this:

// Message to send a message
func (bot *Bot) Message(message string) {
	if message == "" {
		return
	}
	fmt.Printf("Bot: " + message + "\n")
	fmt.Fprintf(bot.conn, "PRIVMSG "+bot.channel+" :"+message+"\r\n")
}

everytime when I then try to use this function I get this error and the program crashes

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x463d73]

I'm unsure about how to use the & and * signs correctly to achieve what I want to do.

I thought a goroutine is something that is for multithreading and is done by saying "go [do something]" but I don't use that anywhere.

Edit:
Solution

Thanks I found the solution! For those interested:
I created a new instance of Bot in the place where I called the Message() function which resulted in an empty conn.

This was the important bit, I stupidly didn't post here. handle() wasn't even a method of Bot which is even more stupid of me.

func handle(line string) {
    ircbot := NewBot();
    // get username, message etc...
	ircbot .CmdInterpreter(username[1], usermessage)
}

and this is the correct way:

func (bot *Bot) handle(line string) {
    // get username, message etc...
	bot.CmdInterpreter(username[1], usermessage)
}

答案1

得分: 4

这里的问题似乎与Connect方法有关,而不是特定于指针:

func (bot *Bot) Connect() (conn net.Conn, err error) {
    ircbot := NewBot()
    conn, err = net.Dial("tcp", bot.server+":"+bot.port)
    // irc connection...
    return bot.conn, nil
}

该方法被定义在(指向)Bot结构体上,但在这一行中创建了一个新的Bot

ircbot := NewBot()

然后继续使用方法所定义的那个(称为bot而不是ircbot)。如果你选择保持NewBotConnect函数分开(这是可以的),那么你应该更改Connect,使其实际上使用一个已实例化的*Bot

func (bot *Bot) Connect() (conn net.Conn, err error) {
    conn, err = net.Dial("tcp", bot.server+":"+bot.port)
    // irc connection...
    return bot.conn, nil
}

并像这样调用它:

bot := NewBot()
conn, err := bot.Connect()

错误信息:

panic: runtime error: invalid memory address or nil pointer dereference

可能是因为你在Connect方法中访问了bot(例如在bot.server中),但它尚未被定义,指针为空。

英文:

The issue here seems to be with the Connect method, and not really with pointers in particular:

func (bot *Bot) Connect() (conn net.Conn, err error) {
	ircbot := NewBot()
	conn, err = net.Dial("tcp", bot.server+":"+bot.port)
	// irc connection...
    return bot.conn, nil
}

The method is defined to be on (a pointer to the) Bot struct, but it creates a new Bot, on this line:

ircbot := NewBot()

and then proceeds to use the one the method is defined on (called bot, not ircbot). If you choose to keep it so that there are separate NewBot and Connect functions (which is fine), then you should change it so that Connect actually uses an instantiated *Bot:

func (bot *Bot) Connect() (conn net.Conn, err error) {
    conn, err = net.Dial("tcp", bot.server+":"+bot.port)
    // irc connection...
    return bot.conn, nil
}

and call it with something like this:

bot := NewBot()
conn, err := bot.Connect()

The error,

panic: runtime error: invalid memory address or nil pointer dereference

is probably because you are accessing bot in the Connect method (e.g. in bot.server) but it has not been defined, and the pointer is nil.

huangapple
  • 本文由 发表于 2016年2月24日 18:31:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/35599597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定