在Golang中创建哈希数组

huangapple go评论96阅读模式
英文:

Making Array of Hashes in Golang

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我对Go语言还很陌生,对于嵌套数据结构有些困惑。下面是我模拟的一个数组哈希表,在Golang中我需要创建这样的结构。我对于需要事先声明变量类型等方面感到困惑。有什么想法吗?

var Array = [
   {name: 'Tom', dates: [20170522, 20170622], images: {profile: 'assets/tom-profile', full: 'assets/tom-full'}},
   {name: 'Pat', dates: [20170515, 20170520], images: {profile: 'assets/pat-profile', full: 'assets/pat-full'}}
   ...,
   ...
]

请注意,Go语言中没有直接的哈希表类型,但你可以使用结构体和切片来实现类似的功能。你可以定义一个结构体来表示每个元素,然后使用切片来存储这些元素。以下是一个可能的实现示例:

type Image struct {
    Profile string
    Full    string
}

type Person struct {
    Name   string
    Dates  []int
    Images Image
}

func main() {
    var Array = []Person{
        {Name: "Tom", Dates: []int{20170522, 20170622}, Images: Image{Profile: "assets/tom-profile", Full: "assets/tom-full"}},
        {Name: "Pat", Dates: []int{20170515, 20170520}, Images: Image{Profile: "assets/pat-profile", Full: "assets/pat-full"}},
        // ...
    }

    // 使用 Array 进行后续操作
}

希望这可以帮助到你!如果你有任何其他问题,请随时问我。

英文:

I'm brand new to Go and having some trouble with nested data structures. Below is a array of hashes I mocked up that I need to make in Golang. I'm just confused with the whole having to declare the variable type beforehand and whatnot. Any ideas?

 var Array = [
   {name: 'Tom', dates: [20170522, 20170622], images: {profile: 'assets/tom-profile', full: 'assets/tom-full'}},
   {name: 'Pat', dates: [20170515, 20170520], images: {profile: 'assets/pat-profile', full: 'assets/pat-full'}} 
    ...,
    ... ]

答案1

得分: 2

在Ruby中,称为“hash”的东西在Go语言中被称为“map”(将键映射到值)。然而,Go是一种静态类型检查的语言。一个map只能将某种类型映射到另一种类型,例如,一个map[string]int将字符串值映射到整数。但这不是你在这里想要的。

所以你需要一个结构体。确实,你需要事先定义类型。你可以这样做:

// 声明一个单独的“Date”类型,你可能想要将其编码为int。
type Date int
type User struct {
Name string
Dates []Date
Images map[string]string
}

现在这个类型被定义了,你可以在另一个类型中使用它:

ar := []User{
User{
Name: "Tom",
Dates: []Date{20170522, 20170622},
Images: map[string]string{"profile":"assets/tom-profile", "full": "assets/tom-full"},
},
User{
Name: "Pat",
Dates: []Date{20170515, 20170520},
Images: map[string]string{"profile":"assets/pat-profile", "full": "assets/pat-full"},
},
}

注意我们将User定义为一个结构体,但将images定义为字符串到图像的映射。你也可以定义一个单独的Image类型:

type Image struct {
Type string // 例如"profile"
Path string // 例如"assets/tom-profile"
}

然后,你将不再将Images定义为map[string]string,而是定义为[]Image,即Image结构体的切片。哪种方式更合适取决于使用情况。

英文:

What is called a 'hash' in Ruby is called a 'map' (translating keys to values) in Go.

However, Go is a statically typechecked language. A map can only map a certain type to another type, e.g. a map[string]int maps string values to integeger. That is not what you want here.

So what you want is a struct. Indeed, you need to define the type beforehand. So what you would do:

// declaring a separate 'Date' type that you may or may not want to encode as int. 
type Date int 
type User struct {
    Name string
    Dates []Date
    Images map[string]string
}

Now that this type is defined, you can use it in another type:

ar := []User{
  User{
    Name: "Tom",
    Dates: []Date{20170522, 20170622},
    Images: map[string]string{"profile":"assets/tom-profile", "full": "assets/tom-full"},
  },
  User{
    Name: "Pat",
    Dates: []Date{20170515, 20170520},
    Images: map[string]string{"profile":"assets/pat-profile", "full": "assets/pat-full"},
  },
}   

Note how we are defining User as a struct, but images as a map of string to image. You could also define a separate Image type:

type Image struct {
  Type string // e.g. "profile"
  Path string // e.g. "assets/tom-profile"
}

You would then not define Images as map[string]string but as []Image, that is, slice of Image structs. Which one is more appropriate depends on the use case.

答案2

得分: 2

你不需要事先声明变量类型,至少在这个简单的例子中不需要,尽管在使用复合字面量初始化值时需要“提及”类型。

例如,[{}](对象数组?)对于Go编译器来说没有意义,相反,你需要写成[]map[string]interface{}{}(键为字符串类型,值可以是任意类型的映射的切片)。

具体解释如下:

  1. [] - 切片,后面跟着任意类型
  2. map - 内置的映射(类似哈希)
  3. [string] - 方括号内是映射键的类型,可以是几乎任意类型
  4. interface{} - 映射值的类型
  5. {} - 初始化/分配整个映射

因此,在Go中,你的示例代码应该是这样的:

var Array = []map[string]interface{}{
    {"name":"Tom", "dates": []int{20170522, 20170622}, "images": map[string]string{"profile": "assets/tom-profile", "full": "assets/tom-full"}},
    {"name":"Pat", "dates": []int{20170515, 20170520}, "images": map[string]string{"profile": "assets/pat-profile", "full": "assets/pat-full"}},
    // ...
}

在这里可以了解更多关于映射和可以使用的键类型的信息:https://golang.org/ref/spec#Map_types

话虽如此,在Go中,大多数情况下,你会首先更具体地定义结构化类型,然后使用它们而不是映射,所以在Go中更合理的做法是这样的:

type User struct {
    Name string
    Dates []int
    Images Images
}

type Images struct {
    Profile string
    Full string
}

var Array = []User{
    {Name:"Tom", Dates:[]int{20170522, 20170622}, Images:Images{Profile:"assets/tom-profile", Full:"assets/tom-full"}},
    {Name:"Pat", Dates:[]int{20170515, 20170520}, Images:Images{Profile:"assets/pat-profile", Full:"assets/pat-full"}},
}
英文:

You don't need to declare the variable type beforehand, at least not in this simple example, although you need to "mention" your types when initializing your values with composite literals.

For example this [{}] (array of objects?) makes no sense to the Go compiler, instead you need to write something like this []map[string]interface{}{} (slice of maps whose keys are strings and whose values can have any type)

To break it down:

  1. [] - slice of whatever type comes after it
  2. map - builtin map (think hash)
  3. [string] - inside the square brackets is the type of the map key,
    can be almost any type
  4. interface{} - the type of the map values
  5. {} - this initializes/allocate the whole thing

So your example in Go would look something like this:

var Array = []map[string]interface{}{
    {"name":"Tom", "dates": []int{20170522, 20170622}, "images": map[string]string{"profile": "assets/tom-profile", "full": "assets/tom-full"}},
    {"name":"Pat", "dates": []int{20170515, 20170520}, "images": map[string]string{"profile": "assets/pat-profile", "full": "assets/pat-full"}},
    // ...
}

Read more on maps and what key types you can use here: https://golang.org/ref/spec#Map_types

That said, in Go, most of the time, you would first define your structured types more concretely and then use them instead of maps, so something like this makes more sense in Go:

type User struct {
    Name string
    Dates []int
    Images Images
}

type Images struct {
    Profile string
    Full string
}

var Array = []User{
    {Name:"Tom", Dates:[]int{20170522, 20170622}, Images:Images{Profile:"assets/tom-profile", Full:"assets/tom-full"}},
    {Name:"Pat", Dates:[]int{20170515, 20170520}, Images:Images{Profile:"assets/pat-profile", Full:"assets/pat-full"}},
}

huangapple
  • 本文由 发表于 2017年4月13日 05:15:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/43379772.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定