Golang中如何在包和函数间共享结构体数组

Golang中如何在包和函数间共享结构体数组 我想在一个名为 structure 的包中定义一个结构体,然后从其他文件和函数中共享并填充该结构体。假设我定义了这样一个结构体:

package structure

type Try struct {
	NameOne string
	Street []string
}

其中 NameOne 是一个人的名字,例如“Bob”,Street 是他拥有房屋的街道名称,考虑到他可能拥有不止一处房屋。然后我尝试从主函数中填充这个结构体:

package main

import (
	"./str"
	"fmt"
)

func main(){

	var list structure.Try
	
	list.NameOne = "Joe"
	list.Street = "Frist"
	list.NameOne = "Frank"
	list.Street = "Ninth"
	fmt.Println(list)
}

但我显然只得到了最后一个 NameOneStreet,我怎样才能获取所有数据呢?我也尝试过声明 var list []structure.Try 而不是 var list structure.Try,但如果这样做,在主函数中所有 list.* 都会得到 list.NameOne undefined (type []structure.Try has no field or method NameOne) 的错误。

添加此数据后的图形化示例:

       NameOne           Street
--------------------------------------------------------
                          First street number 23
Bob                       Second street number 15
                          Ninth street number 9
--------------------------------------------------------
Jim                       Fifth street number 16
--------------------------------------------------------

因此,如果我打印 Bob 的数据,我应该得到他的名字和三条街道;而如果我打印 Jim 的数据,我应该只得到他的名字和一条街道。

希望你能提供帮助, 谢谢


更多关于Golang中如何在包和函数间共享结构体数组的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

我也尝试声明 var list []structure.Try 而不是 var list structure.Try,但如果我这样做,在 main 函数中所有 list.* 的地方都会得到 list.NameOne undefined (type []structure.Try has no field or method NameOne) 的错误。

展示一下这段代码。

更多关于Golang中如何在包和函数间共享结构体数组的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


package main

import (
	"./str"
	"fmt"
)

func main(){

	var list []structure.Try
	
	list.NameOne = "Joe"
	list.Street = "Frist"
	list.NameOne = "Frank"
	list.Street = "Ninth"
	fmt.Println(list)
}
func main() {

	var list = new(structure.Try)

	list.NameOne = "Joe"
	list.Street = make([]string, 2)
	list.Street[0] = "Frist"
	list.NameOne = "Frank"
	list.Street[1] = "Ninth"

	for key, v := range list.Street {
		fmt.Println(key, ' ', v)
	}

}

谢谢,@BigBoulard,还有最后一个问题,因为我事先并不知道会有多少条街道(你在 make 函数里写了 2),我该如何解决这个问题?我的意思是,街道数量可能是 1、5、0 或其他任何数字。有没有办法先声明它,然后根据实际数量来追加值?另外,如果我没理解错的话,你现在是用 Frank 覆盖了 Joe 的名字,而我想要的是创建一个我写的那个结构体的数组,这样我就能打印 Joe 和他所有的街道,或者 Frank 和他所有的街道了。

你好 @wecandoit

抱歉,我刚才读得太快了……这里应该会好一些

func main() {
	var list []*structure.Try

	var contact1 = new(structure.Try)
	contact1.NameOne = "Joe"
	contact1.Street = make([]string, 1)
	contact1.Street[0] = "Frist"
	contact1.Street = append(contact1.Street, "Strauss", "Blair", "Oxford")
	list = append(list, contact1)

	var contact2 = new(structure.Try)
	contact2.NameOne = "Frank"
	contact2.Street = make([]string, 1)
	contact2.Street[0] = "Ninth"
	contact2.Street = append(contact2.Street, "Washington", "McGregor", "O'Sullivan")
	list = append(list, contact2)

	for _, v := range list {
		fmt.Print((*v).NameOne, ": ")
		for _, v2 := range (*v).Street {
			fmt.Print(v2, " - ")
		}
		fmt.Println("")
	}

根据你的需求,你需要的是一个结构体切片(slice of structs),而不是单个结构体。以下是正确的实现方式:

首先在 structure 包中定义结构体:

// structure/structure.go
package structure

type Try struct {
    NameOne string
    Street  []string
}

然后在主函数中正确使用:

package main

import (
    "./structure"
    "fmt"
)

func main() {
    // 创建结构体切片
    var list []structure.Try
    
    // 添加第一个人的数据
    bob := structure.Try{
        NameOne: "Bob",
        Street: []string{
            "First street number 23",
            "Second street number 15", 
            "Ninth street number 9",
        },
    }
    list = append(list, bob)
    
    // 添加第二个人的数据
    jim := structure.Try{
        NameOne: "Jim",
        Street: []string{"Fifth street number 16"},
    }
    list = append(list, jim)
    
    // 打印所有数据
    for _, person := range list {
        fmt.Printf("Name: %s\n", person.NameOne)
        fmt.Println("Streets:")
        for _, street := range person.Street {
            fmt.Printf("  - %s\n", street)
        }
        fmt.Println("---")
    }
    
    // 或者打印特定人的数据
    fmt.Println("\nBob's data:")
    for _, person := range list {
        if person.NameOne == "Bob" {
            fmt.Printf("%+v\n", person)
        }
    }
}

如果你需要动态添加数据,可以使用以下方式:

package main

import (
    "./structure"
    "fmt"
)

func main() {
    var list []structure.Try
    
    // 创建并添加Bob的数据
    bob := structure.Try{NameOne: "Bob"}
    bob.Street = append(bob.Street, "First street number 23")
    bob.Street = append(bob.Street, "Second street number 15")
    bob.Street = append(bob.Street, "Ninth street number 9")
    list = append(list, bob)
    
    // 创建并添加Jim的数据
    jim := structure.Try{NameOne: "Jim"}
    jim.Street = append(jim.Street, "Fifth street number 16")
    list = append(list, jim)
    
    // 访问和修改数据
    fmt.Println("Total people:", len(list))
    
    // 访问第一个人的第一条街道
    if len(list) > 0 && len(list[0].Street) > 0 {
        fmt.Println("Bob's first street:", list[0].Street[0])
    }
}

如果你需要在多个函数间共享这个切片,可以将其作为参数传递:

package main

import (
    "./structure"
    "fmt"
)

func addPerson(list *[]structure.Try, name string, streets []string) {
    person := structure.Try{
        NameOne: name,
        Street: streets,
    }
    *list = append(*list, person)
}

func printAll(list []structure.Try) {
    for i, person := range list {
        fmt.Printf("Person %d: %s\n", i+1, person.NameOne)
        for j, street := range person.Street {
            fmt.Printf("  Street %d: %s\n", j+1, street)
        }
    }
}

func main() {
    var list []structure.Try
    
    // 使用函数添加数据
    addPerson(&list, "Bob", []string{
        "First street number 23",
        "Second street number 15",
        "Ninth street number 9",
    })
    
    addPerson(&list, "Jim", []string{"Fifth street number 16"})
    
    // 打印所有数据
    printAll(list)
}

这样你就可以在包和函数间正确共享和操作结构体数组了。

回到顶部