Golang中如何访问其他包的结构体

Golang中如何访问其他包的结构体 如何从一个包中访问另一个包中创建的结构体?

package a

func Somefunction() {
	A,err := something({a:"abc",b:"def"})  // returns pointer to struct
}

package b

// 如何从这个包中访问指向结构体 A 的指针??

我尝试像下面这样将结构体设为全局变量,但得到了空结构体

package a

var A struct = {}

....  (same as before)

package b

fmt.Printf("%v", a.A)

而我得到的是空白结果…


更多关于Golang中如何访问其他包的结构体的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

好的,没问题。

更多关于Golang中如何访问其他包的结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


嗯,问题是,我完全不清楚你的最终目标是什么。不过正如我所说,直接返回一个值可能是最好的选择。

抱歉,我不太明白这段代码想要说明什么。

不过,看起来你似乎想为你的电影和音乐数据库构建一个HTTP前端,所以最好还是将数据存储在合适的数据库中,而不是仅仅放在内存里。

以下是代码的更多细节,我需要将它们分成两个包。

package a

func Somefunction() {
	A, err := something({a:"abc",b:"def"})
}

func DoSomethingWithMovie(A) {
	// 执行一些操作
}


package b

func Router() *mux.Router {
	router.HandleFunc("/movie", movie).Methods("POST")
	router.HandleFunc("/music", music).Methods("POST")
}

func movie {
	a.DosomethingWithMovie(A)
}

NobbZ:

由于使用了 :=,局部变量 Aerr 被声明为推断类型。

非常感谢你对第一个问题的回答。由于使用了 :=,局部变量 Aerr 被声明为推断类型。这一点非常清楚!

不过,关于“尽量避免共享的可变全局状态,否则将很难甚至无法正确调试你的代码。”这一点,你能详细说明一下吗?

你能想到任何方法,可以在不使用全局变量的情况下,在另一个包中使用由其他包中的函数创建的结构体来传递数据吗?

在以下代码片段中:

package a

var A struct = {}

func Somefunction() {
	A,err := something({a:"abc",b:"def"})  // returns pointer to struct
}

我假设这就是你第二个示例的意思,当调用 Somefunction() 时会发生以下情况:

  1. 由于使用了 :=,局部变量 Aerr 被声明,其类型由编译器推断。
  2. something({a:"abc",b:"def"}) 的返回值被赋值给局部变量 Aerr
  3. 你的函数结束,局部变量从栈中移除。
  4. 在整个过程中,全局变量 A 没有被触及。

你可能想要使用:

package a

var A struct = {}

func Somefunction() {
	var err error
	A, err = something({a:"abc",b:"def"})  // returns pointer to struct
}

或者更好的做法是:

package a

var A struct = {}

func Somefunction() (struct, error) { // 或者 `something()` 实际的返回类型是什么就用什么。
	return something({a:"abc",b:"def"})  // returns pointer to struct
}

尽量避免使用共享的可变全局状态,否则将很难(甚至不可能)正确地调试你的代码。

在Go中访问其他包的结构体,需要确保结构体类型和字段都是导出的(首字母大写)。以下是几种常见的方法:

方法1:通过导出的函数返回结构体指针

// package a
package a

type MyStruct struct {  // 结构体名称首字母大写
    FieldA string       // 字段首字母大写
    FieldB string
}

var instance *MyStruct

func GetInstance() *MyStruct {
    if instance == nil {
        instance = &MyStruct{
            FieldA: "abc",
            FieldB: "def",
        }
    }
    return instance
}

func CreateNew() *MyStruct {
    return &MyStruct{
        FieldA: "value1",
        FieldB: "value2",
    }
}
// package b
package b

import "yourmodule/a"

func UseStruct() {
    // 通过导出的函数获取实例
    instance := a.GetInstance()
    fmt.Printf("%+v\n", instance)  // 输出: &{FieldA:abc FieldB:def}
    
    // 或者创建新实例
    newInstance := a.CreateNew()
    fmt.Printf("%+v\n", newInstance)
}

方法2:直接访问导出的全局变量

// package a
package a

type MyStruct struct {
    FieldA string
    FieldB string
}

// 导出的全局变量
var GlobalInstance = &MyStruct{
    FieldA: "defaultA",
    FieldB: "defaultB",
}
// package b
package b

import "yourmodule/a"

func UseGlobal() {
    fmt.Printf("%+v\n", a.GlobalInstance)  // 输出: &{FieldA:defaultA FieldB:defaultB}
    
    // 可以修改导出的字段
    a.GlobalInstance.FieldA = "new value"
}

方法3:使用工厂函数模式

// package a
package a

type myStruct struct {  // 小写,不导出结构体
    fieldA string
    fieldB string
}

// 导出的接口
type MyInterface interface {
    GetFieldA() string
    GetFieldB() string
    SetFieldA(string)
}

func New() MyInterface {
    return &myStruct{
        fieldA: "initialA",
        fieldB: "initialB",
    }
}

// 实现接口方法
func (m *myStruct) GetFieldA() string {
    return m.fieldA
}

func (m *myStruct) GetFieldB() string {
    return m.fieldB
}

func (m *myStruct) SetFieldA(value string) {
    m.fieldA = value
}
// package b
package b

import "yourmodule/a"

func UseInterface() {
    obj := a.New()
    fmt.Printf("FieldA: %s\n", obj.GetFieldA())  // 输出: FieldA: initialA
    obj.SetFieldA("updated")
}

针对你代码的修正

// package a
package a

type MyStruct struct {
    A string
    B string
}

var Instance *MyStruct

func Somefunction() {
    Instance = &MyStruct{
        A: "abc",
        B: "def",
    }
}

// 或者直接初始化
var GlobalVar = &MyStruct{
    A: "abc",
    B: "def",
}
// package b
package b

import (
    "fmt"
    "yourmodule/a"
)

func AccessStruct() {
    // 调用函数初始化
    a.Somefunction()
    fmt.Printf("%+v\n", a.Instance)  // 输出: &{A:abc B:def}
    
    // 或者直接访问全局变量
    fmt.Printf("%+v\n", a.GlobalVar)  // 输出: &{A:abc B:def}
}

关键点:

  1. 结构体类型名首字母大写才能被其他包访问
  2. 结构体字段首字母大写才能被其他包访问
  3. 变量名首字母大写才能被其他包访问
  4. 确保在访问前结构体已经被正确初始化
回到顶部