首页 > 其他分享 >Goland 反射的一些注意事项

Goland 反射的一些注意事项

时间:2024-03-24 15:45:53浏览次数:21  
标签:反射 调用 ref 接收者 Goland 注意事项 方法 指针

Goland 反射的一些注意事项

Goland 反射的一些注意事项

reflected := reflect.ValueOf(obj).Elem()
  if reflected.CanInterface() {
    // try in struct receiver
    if c, ok := reflected.Interface().(Parse); ok {
      gormRes.Merge(c.AsGormSQL())
      return
    }
    // try in struct pointer receiver
    if reflected.Kind() == reflect.Struct && reflected.CanAddr() {
      ref := reflected.Addr()
      if c, ok := ref.Interface().(Parse); ok {
        gormRes.Merge(c.AsGormSQL())
        return
      }
    }
  }

注意

在Go语言中,通过反射或直接调用方法时,确实存在一些规则关于结构体和它的指针调用方法的差异。这些规则反映了Go的方法集的概念:

  • 值类型(结构体实例)的方法集包含所有接收者为值类型的方法。
  • 指针类型(指向结构体的指针)的方法集包括所有接收者为值类型或指针类型的方法。

这意味着:

  • 如果你有一个结构体的值,你只能调用那些定义为值接收者的方法。
  • 如果你有一个结构体的指针,你可以调用那些定义为指针接收者的方法,以及那些定义为值接收者的方法。

在反射中,reflect.Value 提供了 Method 方法来调用相关的方法。当你通过反射来调用方法时,调用规则和非反射时的规则保持一致,但是使用的方式略有不同:

  • 当你拥有一个类型的值(非指针)并且想通过反射调用它的方法时,你只能调用值接收者的方法。
  • 当你拥有一个类型的指针并想通过反射调用它的方法时,你可以调用任何方法,不论其接收者是值类型还是指针类型。

这就是为什么传入一个指针对象

第二个需要注意的是

如果使用

type StructDemo struct{
    Name
    Age
}

这种内嵌的方式, 如果Nameage都实现了某个接口, 在通过反射进行interface判断时, 那么StructDemo 也实现了这个接口, 这时候会直接略掉, 这部分需要额外注意下对StructDemo 的接口实现.

为什么要使用指针而不是实例?

  1. 可修改性(Mutability):当你通过反射修改一个对象时,如果你传入了该对象的副本(即结构体的值),任何修改都将只作用于这个副本上,而不会影响原始的对象。如果你想修改原始对象,你需要传入一个指针,这样通过指针反射出的值才能实现对原始对象的修改。
  2. 性能考虑(Performance):当你使用结构体的指针而不是结构体本身时,可以避免复制整个结构体的成本。结构体可能会非常大,如果使用值传递(也就是复制结构体),会有额外的内存和CPU的消耗。使用指针传递可以提高效率。
  3. 接口实现(Interface implementation):在Go中,结构体类型只有在以指针形式接收者(receiver)的方法被定义时,才能实现接口的指针类型方法。当使用反射来检测一个对象是否实现了某个接口时,传入指针使得所有接口方法都可被检测到,而不仅仅是值接收者的方法。

反射中的指针是无法修改值的

package main

import "reflect"

type A struct {
  A1 string
  A2 int
}

type B struct {
  B1 string
  B2 int
}

type Mix struct {
  A
  B
}

func ref(ptr any) {
  ref := reflect.ValueOf(ptr).Elem() //可以试试将.Elm() 去掉
  ref.Field(0).Field(0).SetString("A~")
  println(ref.Kind().String())
}

func main() {
  m := &Mix{
    A: A{
      A1: "A1",
      A2: 1,
    },
    B: B{
      B1: "B1",
      B2: 2,
    },
  }
  ref(m)
  println(m.A.A1)
}

标签:反射,调用,ref,接收者,Goland,注意事项,方法,指针
From: https://www.cnblogs.com/pDJJq/p/18092501/some-precautions-for-goland-reflection-z1qbdmz

相关文章

  • 美区PayPal绑visa卡注意事项
    很多小伙伴都有绑定paypal的需求,但是如果你是绑定美区的paypal这里有几点建议:1、建议使用US的网络环境注册2、使用美区的账号3、使用美区的visa卡三者统一才可以绑定成功,点击获取可以绑定美区paypal的visa卡,办理简单......
  • python环境搭建及特定操作系统注意事项
    文章目录搭建Python环境通用的流程:**1.下载并安装Python解释器****2.验证安装****3.安装包管理器(pip)****4.安装必要的开发工具****5.创建虚拟环境(推荐)****6.安装项目所需的库****7.配置IDE/编辑器**特定操作系统(如Windows、macOS、Linux)的特定步骤或注意事项**Wi......
  • 腾讯视频号直播卖货学习第二十课-IP起号注意事项
    IP号直播需要有长期经营视角1养号阶段避免短视频挂车,因为挂车后会影响短视频质量2注重GPM,不要盲目追求单场GMV或UV【过渡消费粉丝】3封面直播间内容形式做立体人设,多样化,拉长用户新鲜度4宁投流不刷单减少手续费空耗,弄坏直播间模型标签IP账户投放配合品牌/IP较弱,预......
  • 【机器学习】详细解析Sklearn中的StandardScaler---原理、应用、源码与注意事项
    【机器学习】详细解析Sklearn中的StandardScaler—原理、应用、源码与注意事项......
  • Java-Java基础学习(5)-注解和反射以及类的加载过程分析
    4.1注解的理解Annotation是从JDK5.0开始引入的新技术Annotation的作用不是程序本身,可以对程序作出解释(这点和注释comment没什么区别);可以被其他程序(比如:编译器等)读取;Annotation的格式注解是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(v......
  • 【MMD x EEVEE教程】材质篇 • 移除天空球环境反射
    社友们在用eevee做mmd的过程中可能会遇到下边的问题,在一些光滑,或者能反射周围环境的材质中,无法消除hdri环境的反射类似下边这样 教程中的blender文件会在文章末尾给出打开blender,右侧面板中,渲染属性 -> 打开屏幕空间反射 -> 勾选折射 载入一个环境纹理 新建......
  • 北京注册售电公司所需条件与注意事项
    北京注册售电公司:所需条件与注意事项全解析      各位老板好,我是经典世纪胡云帅,随着电力市场的逐步开放和能源结构的转型,售电业务成为了众多投资者关注的焦点。北京,作为中国的首都和经济中心,其电力市场潜力巨大。如果您计划在北京注册一家售电公司,本文将为您详细介绍......
  • 【MMD x EEVEE教程】材质篇 • 替换物体反射
    要用到光程节点中的是相机射线,一个非0即1的值,相机直接看到的为1,通过其它物体间接看到的为0,比如反射折射,漫射。就像我们看镜子一样,我们看到镜子本身,是直接看到的,我们看到镜子中的自己,则是间接看到的 准备两个模型类似下面这样 给个基本的自发光材质,材质混合模式都选alp......
  • Linux mke2fs命令教程:创建和管理你的ext2/ext3/ext4文件系统(附案例详解和注意事项)
    Linuxmke2fs命令介绍mke2fs(makeext2filesystem)命令是用来创建ext2/ext3/ext4文件系统的。它通常在磁盘分区上创建文件系统,设备是对应设备的特殊文件(例如/dev/hdXX)。如果省略了块数,mke2fs会自动计算文件系统的大小。Linuxmke2fs命令适用的Linux版本mke2fs命令在所有......
  • Linux hdparm命令教程:优化硬盘性能和读写速度(附实例详解和注意事项)
    Linuxhdparm命令介绍hdparm是一个用于控制和配置硬盘驱动器的命令行工具。它允许您查看和修改硬盘的参数,包括缓存设置、高级电源管理、硬盘性能等。通过hdparm,您可以优化硬盘的读写速度和性能。Linuxhdparm命令适用的Linux版本hdparm在大多数Linux发行版中都可用,......