3

With this code, is there a better way to loop through all the users and create a new string containing all their Nick values?

package main

import "fmt"

type User struct {
    Nick     string
}


func main() {
    var users [2]User
    users[0] = User{ Nick: "Radar" }
    users[1] = User{ Nick: "NotRadar" }
    names := ":"
    for _, u := range users {
        names += u.Nick + " "
    }
    fmt.Println(names)

}
4

4 回答 4

5

例如,

package main

import (
    "bytes"
    "fmt"
)

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    var buf bytes.Buffer
    buf.WriteByte(':')
    for _, u := range users {
        buf.WriteString(u.Nick)
        buf.WriteByte(' ')
    }
    names := buf.String()
    fmt.Println(names)
}

这避免了由于strings 的串联而导致的大量分配。

你也可以写:

package main

import (
    "fmt"
)

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    var buf []byte
    buf = append(buf, ':')
    for _, u := range users {
        buf = append(buf, u.Nick...)
        buf = append(buf, ' ')
    }
    names := string(buf)
    fmt.Println(names)
}
于 2013-07-31T00:08:05.837 回答
2

看起来你真的想要一个字符串。在这里加入。您可能希望避免原始代码中重复字符串连接的紧密循环;我相当肯定 Go 没有为其原始字符串实现类似绳索的数据结构。

package main

import (
    "fmt"
    "strings"
)

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    userNames := []string{}
    for _, u := range users {
        userNames = append(userNames, u.Nick)
    }
    names := ":" + strings.Join(userNames, " ")
    fmt.Println(names)
}
于 2013-07-31T00:08:35.477 回答
1

不幸的是,我不知道编写该代码的更优雅的方式。

Go 确实有一个String.Join方法,因此如果您创建了一个帮助器,将您的用户数组转换为字符串切片 ( []string),那么您可以将其传递给String.Join.

map我认为 Go 的静态类型和缺少模板使得编写像 Ruby 那样的通用函数变得很困难。

于 2013-07-31T00:09:01.703 回答
1

这就是我在 dyoo 帖子的评论中所说的。有效地重写了连接,以防止必须在列表上迭代额外的时间并分配额外的切片。

func Usernames(users []User) string {
    if len(users) == 0 {
        return ""
    }
    if len(users) == 1 {
        return users[0].Name
    }

    sep := " "
    n := len(users)-1 // From len(sep) * len(a)-1, sep is always len 1 unlike in Join
    for i := 0; i < len(users); i++ {
        n += len(users[i].Name)
    }

    names := make([]byte,n)
    namesp := copy(names, users[0].Name)
    for _,u := range users[1:] {
        namesp += copy(names[namesp:], sep)
        namesp += copy(names[namesp:], u.Name)
    }
    return string(names)
}

作为参考,strings.go 与 strings.Join 来源: http: //golang.org/src/pkg/strings/strings.go

见第 356 行

于 2013-07-31T00:56:58.920 回答