我刚刚开始对golang开玩笑。 我教自己php& jquery很容易&通过创建一个项目来实现这一目标。
我正在尝试使用相同的atm来自学golang,但我已经达到了一定程度 现在要么我错过了这一点,要么只是错误地搜索。
...
好的,我要做的就是制作一个IRC机器人。 一个功能监听频道聊天&如果选择了某些命令 然后它会将相关信息添加到sqlite3数据库。
问题是其中一个命令查询数据库&将返回多行,然后需要将其传递回原始函数&输入到IRC频道。
我遇到的问题是将查询输出返回到原始函数,因为它是多行数据
我导入以下库
fmt
net/textproto
regexp
strings
os
database/sql
_ github.com/mattn/go-sqlite3
func getLineup() {
// Open Database
db, err := sql.Open("sqlite3", "./database.db")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer db.Close()
// Prepare Query
statement, err := db.Prepare("SELECT team, player FROM lineup ORDER BY team DESC;")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Execute Statement
rows, err := statement.Query()
defer rows.Close()
fmt.Println("Lineup:")
for rows.Next() {
var team string
var player string
rows.Scan(&team, &player)
fmt.Printf("%v %v\n", team, player)
}
}
所以我可以打印它,但我需要将它传递给另一个失去了
的功能 ================================UPDATE====================================
好的,这是我的完整代码......
@evanmcdonnal使用上面给出的更新代码,我现在得到错误
bot.go:70: cannot use p (type Player) as type *Player in append
package main
import (
"fmt"
"net/textproto"
"regexp"
"log"
"strings"
"database/sql"
// SQLite3
_ "github.com/mattn/go-sqlite3"
)
type PrivMsg struct {
nick, channel, text string
}
var (
conn *textproto.Conn
err error
ping = regexp.MustCompile("^PING :([a-zA-Z0-9\\.]+)$")
motd = regexp.MustCompile(":End of /MOTD command\\.$")
privmsg = regexp.MustCompile("^:([a-zA-Z0-9`_\\-]+)![a-zA-Z0-9/\\\\\\.\\-]+@[a-zA-Z0-9/\\\\\\.\\-]+ PRIVMSG (#[a-zA-Z0-9]+) :(.*)$")
)
func talk(channel, msg string) {
conn.Cmd("PRIVMSG " + channel + " :" + msg)
}
func handlePing(auth string) {
conn.Cmd("PONG :" + auth)
fmt.Printf("PONG :%s\n", auth)
}
type Player struct {
TeamName string
PlayerName string
}
func getLineup() {
// Open Database
db, err := sql.Open("sqlite3", "./database.db")
if err != nil {
log.Fatal(err)
}
// Prepare Query
statement, err := db.Prepare("SELECT team, player FROM lineup ORDER BY team DESC;")
if err != nil {
log.Fatal(err)
}
// Execute Statement
rows, err := statement.Query()
defer rows.Close()
// Output Code
var Players []*Player
for rows.Next() {
p := &Player{}
if err := rows.Scan(p.TeamName, p.PlayerName); err != nil{
log.Fatal(err)
}
//Players = append(Players, p)
return p.TeamName, p.PlayerName
}
// pass Players to next function/return it whatever
fmt.Println(Players)
}
func handlePrivmsg(pm *PrivMsg) {
if strings.Contains(pm.text, "!add t") {
talk(pm.channel, pm.nick + " added to Terrorists")
saveLineup("T", pm.nick)
}
if strings.Contains(pm.text, "!add ct") {
talk(pm.channel, pm.nick + " added to Counter-Terrorists")
saveLineup("CT", pm.nick)
}
if strings.Contains(pm.text, "!rem") {
talk(pm.channel, pm.nick + " has been removed from the current lineup")
}
if strings.Contains(pm.text, "!votemap") {
talk(pm.channel, pm.nick + " map vote code")
}
if strings.Contains(pm.text, "!moveme") {
talk(pm.channel, pm.nick + " has been moved to Counter-Terrorists")
}
if strings.Contains(pm.text, "!teams") {
getLineup()
//fmt.Println(*tpList)
talk(pm.channel, pm.nick + " will show the current teams")
}
if strings.Contains(pm.text, "!add ct") {
talk(pm.channel, pm.nick + " added to Counter-Terrorists")
}
if strings.Contains(pm.text, "pug-bot") {
talk(pm.channel, "Hello, " + pm.nick + "!")
}
}
func saveLineup(Team, Player string) {
// Open Database
db, err := sql.Open("sqlite3", "./database.db")
if err != nil {
//log.Fatal(err)
fmt.Printf("%s", err)
}
// Get Current Lineup
rows, err := db.Query("SELECT team, player FROM lineup WHERE player = ?;", Player)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
if Player == Player {
fmt.Println("You have already added yourself")
} else {
// Insert new Player
db.Exec(
"INSERT INTO lineup (team, player) VALUES (?, ?);",
Team,
Player,
)
}
}
func handleMotd() {
conn.Cmd("JOIN #ircchannel")
fmt.Println("JOIN #ircchannel")
}
func parseLine(line string) {
// Channel activity
if match := privmsg.FindStringSubmatch(line); match != nil {
pm := new(PrivMsg)
pm.nick, pm.channel, pm.text = match[1], match[2], match[3]
handlePrivmsg(pm)
return
}
// Server PING
if match := ping.FindStringSubmatch(line); match != nil {
handlePing(match[1])
return
}
// End of MOTD (successful login to IRC server)
if match := motd.FindString(line); match != "" {
handleMotd()
return
}
}
func main() {
conn, err = textproto.Dial("tcp", "irc.server.org:6667")
if err != nil {
fmt.Printf("%s", err)
return
}
conn.Cmd("NICK pug-bot\n\rUSER pug-bot 8 * :pAsSwOrD")
for {
text, err := conn.ReadLine()
if err != nil {
fmt.Printf("%s", err)
return
}
go parseLine(text)
fmt.Println(text)
}
}
基本上我想将sql查询的结果传回talk(pm.channel, pm.nick + " SQL QUERY RESULT")
irc talk部分
答案 0 :(得分:0)
我认为您未能理解的是如何在Go应用程序中建模数据(从数据库返回后)。您用来存储您读取的值的变量仅限于循环范围并且是单例,您将如何返回集合?好吧,使用当然的集合!
所以这是我要考虑的两个选项;
1)将所有内容连成一个大字符串。如果您要在他之后很快将输出转储到控制台并且您没有任何真正的处理要做,那么在循环之前声明一个字符串可能是最简单的,保持您的扫描原样,将结果附加到一些常见格式的字符串,如逗号分隔,然后将其传递给函数/将其写入IRC或其他任何内容。
2)使用实际的集合。在任何严肃的程序中,你可能会对来自数据库的数据做更多的事情而不是打印只打印它。更现实的实现是创建具有teamName和playerName字段的Player结构。在循环之前,如果您知道将返回多少结果,则初始化一片玩家或数组。在循环中,您将创建一个新实例,并使用append函数将其添加到切片中。在循环之后,您将切片/数组传递给需要使用下一个数据的任何内容。
以下是几个样本。请注意,这些都是未经测试的,我不考虑性能。例如,如果性能是一个问题,你可能应该使用类似这样的字符串连接How to efficiently concatenate strings in Go?
type Player struct {
TeamName string
PlayerName string
}
var Players []*Player
for rows.Next() {
p := &Player{}
if err := rows.Scan(p.TeamName, p.PlayerName); err != nil{
// handle error
}
Players = append(Players, p)
}
// pass Players to next function/return it whatever
// simpler less robust option 1
lineUp := ""
for rows.Next() {
var team string
var player string
rows.Scan(&team, &player)
lineUp += team + ":" + player "\n"
}
return lineUp
答案 1 :(得分:0)
尝试将您的团队和玩家置于结构
中type teamplayer struct {
team string
player string
}
现在,在您将查询数据库的函数中,创建一个teamplayer列表
var tpList []teamplayer
for rows.Next() {
var tp teamplayer
if err := rows.Scan(&tp.team, &tp.player); err != nil{
//process what to do in case of error
}
tplist = append (tplist, tp)
}//end of for loop
return tplist