dsu89430 2015-11-30 17:46
浏览 85
已采纳

Golang-具有许多定界符的字符串以切片或构造

I have the following string returned as response from a TCP connection :

220 Connected.
command:connect
email:ERROR_MAIL_MISSING
status:CMD_ERROR
end

I want actually to transform this response to the following golang struct :

type Message struct {
    Key string
    Value string
}

type Response struct {
    Connect string
    Messages []Message
}

If 220 Connected is always present means :

Response.Connect => TRUE

All response between 220 Connected. and end can be accessed using :

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

This is what I actually achieved :

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

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

Any hint how this can be achieved ? I'm a newbie with Golang

  • 写回答

1条回答 默认 最新

  • dongluolie3487 2015-11-30 17:56
    关注

    You need to do a bit more work to extract the data you want. Here's a sample program that correctly populates the Messages array. I'll update with some notes on what's I did to move from your attempt to what you're looking for.

    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.
    command:connect
    email:ERROR_MAIL_MISSING
    status:CMD_ERROR
    end`
            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

    Alright, so first lets list some problems. In your attempt the for loop looks like this;

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

    This isn't consistent with your types/data layout. On every iteration you create a new Response instance, you actually only need one. What you want on each iteration is a new Message instance. This causes a few problems, firstly the data you're looking at isn't a response, it's a message, secondly you keep overwriting the previous one (that object is only scoped for the loop). To correct this we instantiate the Response object before the loop. Secondly, you need a second split in order to get your data out. So inside the loop we split on a colon to separate the key and value of each message. Then I have a quick check on the length before adding it (I got a panic on first run, the first if probably failed, meaning you need to edit that a bit. If you don't get 220 for connected you want to set that value to false, you should do the message split an a final else but simply not being 220 Connected. isn't sufficient to assume the current item is a Message which is why I added bounds check). Note that inside this loop I instantiate a new message for each key value pair. We use append there to append to the Messages array, not appending Response's onto eachother (that will never work since it's a struct, not a slice or map). This also makes it so the Message persists rather than going out of scope each time we hit the bottom of the loop (m will go out of scope but the instance in r.Messages will still be around).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?