更清洁的方式迭代数组+从值创建一个字符串

时间:2013-07-30 23:50:00

标签: go

使用此代码,是否有更好的方法来遍历所有用户并创建包含所有Nick值的新字符串?

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 个答案:

答案 0 :(得分:4)

例如,

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

由于string s的串联,这避免了大量的分配。

你也可以写:

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

答案 1 :(得分:1)

看起来你真的想要strings.Join。您可能希望避免原始代码中重复字符串连接的紧密循环;我很确定Go没有为其原始字符串实现rope-like数据结构。

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分: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 with strings.Join source: http://golang.org/src/pkg/strings/strings.go

见第356行