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

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).

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题