Golang Go语言中已经实例化的结构体,能不能不使用反射,通过变量的方法来访问?

发布于 1周前 作者 songsunli 来自 Go语言

var p Person {}

p.name 这个 name 能不能通过字符串变量来代替访问?

类似 js 的 p[“aa”+bb]

请问这样设计的考虑是什么? 因为 p 和 p 的成员在编译的时候都已经确定了 为什么还不能通过变量来确定访问的是哪一个?


Golang Go语言中已经实例化的结构体,能不能不使用反射,通过变量的方法来访问?
9 回复

主要是能做到这件事的,by definition 就是叫反射(
Js 可以做是因为按定义,js object 就是 hash table

更多关于Golang Go语言中已经实例化的结构体,能不能不使用反射,通过变量的方法来访问?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


呃呃,不知道 go 有没有编译插件,编译的时候扫描 AST ,直接生成你想要的方法就行,这样也不需要反射

编译后的代码访问 p.name 时靠的是偏移,而不是成员名。假设 p 的地址是 0x1234 ,那访问 p.name 可能就编译成 *(0x1234 + 0)、p.age 就编译成 *(0x1234 + 8)、p.gender 编译成 *(0x1234 + 12)……
要想通过成员名称来访问,你就得自己算这个偏移关系,对于有些语言,你或许还得自己维护一份符号表——然后你的这个行为,就叫反射

你要用变量当 key 为啥不用 map

Go 不是 js 不追求灵活性。获取 struct 的 field 直接.name 肯定是最明确的,额外增加一种方法反而会提高语言复杂度和开发者阅读 /维护成本

可以的,去研究一下 golang 的 reflect 包,实例化之后依然可以通过反射更改里面的属性或者方法。很多框架都是基于反射做的。
https://github.com/bugfan/rest
这个是我做的自动生成 curd api 的框架,其中就用到了大量反射😄

用反射库做,看下 FieldByName 这个 api 。当然反射性能差,慎用。

把类里所有变量,都建立对应的变量指针, 放到 map 里面, 这样通过名字就可以获取到这些变量指针, 然后就可以用了。重载[]这个操作符, 基本就可以了,也不需要什么反射了。

当然可以,在Go语言中,你可以直接通过变量的方法来访问已经实例化的结构体的字段和方法,而无需使用反射。反射虽然在某些高级或动态场景中非常有用,但在大多数情况下,直接访问是更直接、更高效的方式。

对于一个已定义的结构体类型,你可以直接创建该类型的实例,并通过点操作符(.)来访问其字段或调用其方法。例如:

type Person struct {
    Name string
    Age  int
}

func (p Person) Greet() {
    fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    // 直接访问字段
    fmt.Println(p.Name)
    fmt.Println(p.Age)
    // 调用方法
    p.Greet()
}

在这个例子中,我们定义了一个Person结构体,并为其添加了一个方法Greet。在main函数中,我们创建了Person的实例p,并通过直接访问的方式打印了其字段,调用了其方法。

总的来说,直接访问结构体的字段和方法是Go语言中的标准做法,它提供了更好的性能、更清晰的代码以及更少的运行时开销。只有在需要动态类型检查或操作时才考虑使用反射。

回到顶部