【GO】panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

简介: 【GO】panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

错误翻译理解

不能返回字段或者方法的值

报错代码

定义俩个结构体,People 和 PeopleParent

package main
import (
  "fmt"
  "reflect"
)
type PeopleParent struct {
  kaka string
}
type People struct {
  PeopleParent
  name string
  age  int
}

定义方法valueAPI方法

func valueAPI(obj interface{}) {
  valueOf := reflect.ValueOf(obj)
  // 获取所有属性值
  for i := 0; i < valueOf.NumField(); i++ {
    value := valueOf.Field(i)
    // {}
    //咔咔
    //24
    fmt.Println(value)
  }
  // 获取父类属性
  fieldByIndex := valueOf.FieldByIndex([]int{0, 0})
  fmt.Println(fieldByIndex.Interface()) // 咔咔的父类属性
}

main方法调用valueAPI

func main() {
  p := People{
    PeopleParent: PeopleParent{kaka: "咔咔的父类属性"},
    name:         "咔咔",
    age:          24,
  }
  typeAPI(p)
  valueAPI(p)
}

报错截图

image.png


问题分析


我们根据学习PHP的经验来分析这个错误,在PHP中一个属性有三种访问方式,私有的,可继承的,公共的。那么在go中,我们有公开的和私有的。但是在go语言的表现方式是属性的大小写和方法的大小写。

这个时候我们应该就可以反映过来了,在上面案例,我们获取的是父类属性的正射,但是报错返回的是不能返回字段或者属性

然后我们回过头在来看一下,发现我们父类的kaka属性确实是小写,那么咱们更改为大写后在编译一次


更改后的源码

package main
import (
  "fmt"
  "reflect"
)
type PeopleParent struct {
  Kaka string
}
type People struct {
  PeopleParent
  name string
  age  int
}
func (p *People) eat() {
  fmt.Println("咔咔")
}
func main() {
  p := People{
    PeopleParent: PeopleParent{Kaka: "咔咔的父类属性"},
    name:         "咔咔",
    age:          24,
  }
  valueAPI(p)
}
func valueAPI(obj interface{}) {
  valueOf := reflect.ValueOf(obj)
  // 获取所有属性值
  for i := 0; i < valueOf.NumField(); i++ {
    value := valueOf.Field(i)
    // {}
    //咔咔
    //24
    fmt.Println(value)
  }
  // 获取父类属性
  fieldByIndex := valueOf.FieldByIndex([]int{0, 0})
  fmt.Println(fieldByIndex.Interface()) // 咔咔的父类属性
}

屏幕快照 2022-05-18 下午11.18.59.png

相关文章
|
4月前
|
Go 索引
internal\model\data_support.go:17:10: cannot use _ as value or type
internal\model\data_support.go:17:10: cannot use _ as value or type
|
6月前
|
自然语言处理 Go 索引
startOffset must be non-negative, and endOffset must be >= startOffset, and offsets must not go backwards startOffset=615,endOffset=617,lastStartOffset=616 for field 'convContent.content'
【7月更文挑战第4天】startOffset must be non-negative, and endOffset must be >= startOffset, and offsets must not go backwards startOffset=615,endOffset=617,lastStartOffset=616 for field 'convContent.content'
|
5月前
|
Go
实验深度理解Go中try...catch...的panic、defer、recover用法
文章通过实验代码演示了Go语言中如何使用panic、defer和recover函数来模拟try...catch...的异常处理机制,并详细解释了每个函数的作用和在异常处理中的使用场景。
42 0
|
7月前
|
Go
go:embed cannot apply to var inside【已解决】
go:embed cannot apply to var inside【已解决】
45 2
|
8月前
|
Go 开发者
Golang深入浅出之-Go语言 defer、panic、recover:异常处理机制
Go语言中的`defer`、`panic`和`recover`提供了一套独特的异常处理方式。`defer`用于延迟函数调用,在返回前执行,常用于资源释放。它遵循后进先出原则。`panic`触发运行时错误,中断函数执行,直到遇到`recover`或程序结束。`recover`在`defer`中捕获`panic`,恢复程序执行。注意避免滥用`defer`影响性能,不应对可处理错误随意使用`panic`,且`recover`不能跨goroutine捕获panic。理解并恰当使用这些机制能提高代码健壮性和稳定性。
174 2
|
8月前
|
Go
Go语言中的异常处理:理解panic与recover
【2月更文挑战第7天】Go语言虽然以简洁和直接错误处理机制而著称,但它也提供了`panic`和`recover`这两个内置函数来处理程序中的异常情况。本文将深入探讨Go语言中的异常处理机制,包括`panic`和`recover`的使用场景、原理以及最佳实践,帮助读者更好地理解如何在Go中处理异常情况。
|
8月前
|
网络协议 BI Go
Go-异常处理(defer recover panic)
Go-异常处理(defer recover panic)
83 0
|
编译器 Go
Go学习笔记-defer、panic、recover分析
Go学习笔记-defer、panic、recover分析
93 1
Go学习笔记-defer、panic、recover分析
|
存储 Cloud Native Go
Go 语言中 panic 和 recover 搭配使用
Go 语言中 panic 和 recover 搭配使用
|
编译器 Go
Go 语言怎么解决编译器错误“err is shadowed during return”?
Go 语言怎么解决编译器错误“err is shadowed during return”?
82 0