Golang - 具有许多分隔符的字符串,用于切片或结构化

时间:2015-11-30 17:46:45

标签: go

我有以下字符串作为TCP连接的响应返回:

220 Connected.\ncommand:connect\nemail:ERROR_MAIL_MISSING\nstatus:CMD_ERROR\nend

我希望将此响应转换为以下golang结构:

type Message struct {
    Key string
    Value string
}

type Response struct {
    Connect string
    Messages []Message
}

如果始终存在220已连接,则表示:

Response.Connect => TRUE

220 Connected之间的所有响应。和结束可以使用:

访问
Response[0].Key => "command"
Response[0].Value => "connect"

这就是我实际取得的成就:

result, err := ioutil.ReadAll(conn)
        data := strings.Split(string(result), "\n")

        for i := range data {
                Reply := new(Response)
                if data[i] == "220 Connected." {
                        Reply.Connect = "TRUE"
                        Response = append(Response, Reply)
                }
        }

任何提示如何实现这一目标?我是Golang的新手

1 个答案:

答案 0 :(得分:1)

您需要做更多工作来提取所需的数据。这是一个正确填充Messages数组的示例程序。我会更新一些关于我从你的尝试转移到你正在寻找什么的做法的笔记。

package main

import "fmt"
import "strings"


type Message struct {
    Key string
    Value string
}

type Response struct {
    Connect string
    Messages []Message
}
func main() {
    result := `220 Connected.\ncommand:connect\nemail:ERROR_MAIL_MISSING\nstatus:CMD_ERROR\nend`
        data := strings.Split(string(result), "\\")

    r := &Response{}
        for i := range data {
                if data[i] == "220 Connected." {
                        r.Connect = "TRUE"
                } else {
            tokens := strings.Split(data[i], ":")
            if len(tokens) == 2 {
                m := Message{tokens[0], tokens[1]}
                r.Messages = append(r.Messages, m)
            }
        }
        }
        for i := range r.Messages {
             fmt.Println(r.Messages[i])
        }
}

https://play.golang.org/p/Hs8aqYPyuM

好吧,首先让我们列出一些问题。在你的尝试中,for循环看起来像这样;

  for i := range data {
            Reply := new(Response)
            if data[i] == "220 Connected." {
                    Reply.Connect = "TRUE"
                    Response = append(Response, Reply)
            }
    }

这与您的类型/数据布局不一致。在每次迭代中,您创建一个新的Response实例,实际上只需要一个实例。您希望每次迭代都需要一个新的Message实例。这会导致一些问题,首先,您正在查看的数据不是响应,它是一条消息,其次是您继续覆盖前一个(该对象仅限于循环的范围)。为了纠正这个问题,我们在循环之前实例化Response对象。其次,您需要进行第二次拆分才能获取数据。因此,在循环内部,我们拆分冒号以分隔每条消息的键和值。然后我在添加它之前快速检查长度(我在第一次运行时遇到了恐慌,第一次可能失败了,这意味着你需要编辑一下。如果你没有得到220连接你想要设置如果将值设置为false,则应该将消息拆分为最后的其他但仅仅是220 Connected.不足以假设当前项为Message这就是我添加边界检查的原因)。请注意,在此循环中,我为每个键值对实例化一条新消息。我们使用追加附加到Messages数组,而不是将Response附加到彼此上(因为它是结构,而不是切片或地图,所以永远不会有效)。这也使得Message持续存在而不是在每次触及循环底部时超出范围(m将超出范围,但r.Messages中的实例仍将是左右)。