gpt4 book ai didi

oop - 反射(reflect)嵌入结构的类型

转载 作者:数据小太阳 更新时间:2023-10-29 03:37:55 25 4
gpt4 key购买 nike

我目前正在按照我在网上找到的教程尝试一些 OOP 风格的 Go。

到目前为止,它非常吸引人(让我想起试图将 OOP 强制转换为 ANSI-C)。

然而,只有一件事困扰着我,我似乎无法解决。

我如何才能反射(reflect)嵌入结构的类型名称?

我在网上找到的所有信息都说不能反射(reflect)嵌入结构,因为嵌入结构无法直接访问它。

这完全准确吗?如果是这样,解决以下问题(下面的代码)的正确方法是什么?

基本上,该程序会打印出三种动物的名称,然后是括号中嵌入结构的类型名称,然后是相应动物的“声音”。

对于名为“Rover”的狗,它将打印“Rover(动物):BARK BARK”。

现在,显然,“Rover(动物)”并不是特别有用。理想情况下,这应该是“Rover (Dog)”(嵌入结构的类型名称,而不是嵌入结构)。

这就是我的问题。我怎样才能反射(reflect)嵌入结构的类型,使“流浪者(动物)”变成“流浪者(“狗”)”,“朱利叶斯(动物)”变成“朱利叶斯(猫)”等?

package main

import (
"fmt"
"reflect"
)

type Animal struct {
Name string
mean bool
}

type AnimalSounder interface {
MakeNoise()
}

type Dog struct {
Animal
BarkStrength int
}

type Cat struct {
Basics Animal
MeowStrength int
}

type Lion struct {
Basics Animal
RoarStrength int
}

func (dog *Dog) MakeNoise() {
dog.PerformNoise(dog.BarkStrength, "BARK")
}

func (cat *Cat) MakeNoise() {
cat.Basics.PerformNoise(cat.MeowStrength, "MEOW")
}

func (lion *Lion) MakeNoise() {
lion.Basics.PerformNoise(lion.RoarStrength, "ROAR!! ")
}

func MakeSomeNoise(animalSounder AnimalSounder) {
animalSounder.MakeNoise()
}

func main() {
myDog := &Dog{
Animal{
Name: "Rover", // Name
mean: false, // mean
},
2, // BarkStrength
}

myCat := &Cat{
Basics: Animal{
Name: "Julius",
mean: true,
},
MeowStrength: 3,
}

wildLion := &Lion{
Basics: Animal{
Name: "Aslan",
mean: true,
},
RoarStrength: 5,
}

MakeSomeNoise(myDog)
MakeSomeNoise(myCat)
MakeSomeNoise(wildLion)
}

func (animal *Animal) PerformNoise(strength int, sound string) {
if animal.mean == true {
strength = strength * 5
}

fmt.Printf("%s (%s): \n", animal.Name, reflect.ValueOf(animal).Type().Elem().Name())

for voice := 0; voice < strength; voice++ {
fmt.Printf("%s ", sound)
}

fmt.Println("\n")
}

最佳答案

好的。

然后回答(或至少尝试)我自己的问题,提供我认为可能是处理此问题的正确方法(至少是最直接的方法)。

为简洁起见,我更改了所有版本

func (cat/dog/lion *Cat/*Dog/*Lion) MakeNoise(){}

func (animal *Cat/*Dog/*Lion) MakeNoise(){}

据我所知,这应该不会真正损害可读性,也不会引入任何副作用。

“MakeNoise()”的所有迭代现在只提供第三个参数这与作为字符串的嵌入结构的类型名称相同。

“PerformNoise()”接受该参数(“animalType”)并简单地将其附加到输出

我是

fmt.Printf("%s (%s): \n", animal.Name, animalType)

完整的更新代码:

package main

import (
"fmt"
"reflect"
)

type Animal struct {
Name string
Type string
mean bool
}

type AnimalSounder interface {
MakeNoise()
}

type Dog struct {
Animal
BarkStrength int
}

type Cat struct {
Basics Animal
MeowStrength int
}

type Lion struct {
Basics Animal
RoarStrength int
}

func (animal *Dog) MakeNoise() {
animal.PerformNoise(animal.BarkStrength, "BARK", reflect.ValueOf(animal).Type().Elem().Name())
}

func (animal *Cat) MakeNoise() {
animal.Basics.PerformNoise(animal.MeowStrength, "MEOW", reflect.ValueOf(animal).Type().Elem().Name())
}

func (animal *Lion) MakeNoise() {
animal.Basics.PerformNoise(animal.RoarStrength, "ROAR!! ", reflect.ValueOf(animal).Type().Elem().Name())
}

func MakeSomeNoise(animalSounder AnimalSounder) {
animalSounder.MakeNoise()
}

func main() {
myDog := &Dog{
Animal{
Name: "Rover", // Name
mean: false, // mean
},
2, // BarkStrength
}

myCat := &Cat{
Basics: Animal{
Name: "Julius",
mean: true,
},
MeowStrength: 3,
}

wildLion := &Lion{
Basics: Animal{
Name: "Aslan",
mean: true,
},
RoarStrength: 5,
}

MakeSomeNoise(myDog)
MakeSomeNoise(myCat)
MakeSomeNoise(wildLion)
}

func (animal *Animal) PerformNoise(strength int, sound string, animalType string) {
if animal.mean == true {
strength = strength * 5
}

fmt.Printf("%s (%s): \n", animal.Name, animalType)

for voice := 0; voice < strength; voice++ {
fmt.Printf("%s ", sound)
}

fmt.Println("\n")
}

PS:重申一下。我不想用这种“假的”OOP 风格来编写我的所有代码。

它增加了一大堆不必要的抽象,并且需要对流程进行新的设计考虑。

不过,我确实认为这是试验该语言的基本功能集的好方法。

关于oop - 反射(reflect)嵌入结构的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49915277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com