go 笔记 十二章 断言 assertion 和 反射 reflect

这篇具有很好参考价值的文章主要介绍了go 笔记 十二章 断言 assertion 和 反射 reflect。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

断言
把一个接口类型指定为它的原始类型


type User struct {
	Username string
	Email    string
}

type Admin struct {
	User
}

func (u User) sayHello() {
	fmt.Println("Hello", u.Username)
}

func check(v interface{}) {
	// v 就是断言传进来的类型是 User
	v.(User).sayHello()
}

func checkEnhanced(v interface{}) {
	// v 就是断言传进来的类型是 User
	switch v.(type) {
	case User:
		fmt.Println("User")
		v.(User).sayHello()
	case Admin:
		fmt.Println("Admin")
	default:
		fmt.Println("Unknown")
	}
}

func main() {
	u := User{
		Username: "Rizky",
		Email:    "",
	}
	//check(u)
	checkEnhanced(u)
}

反射
官方说法:在编译时不知道类型的情况下,可更新变量、运行时查看值、调用方法以及直接对他们的布局进行操作的机制,称为反射。
通俗说法:可以知道变量原始数据类型和内容、方法等,并且可以进行一定的操作

为什么要用反射?
接受到类型不固定的数据时,需要写太多 switch case 断言
此时代码不灵活,通用性差
反射可以无视类型,直接操作数据

反射的几个方法的
reflect.TypeOf() // 获取类型
reflect.ValueOf() // 获取值
reflect.ValueOf().Kind() // 获取类型
reflect.ValueOf().Interface() // 获取值

通过反射调用方法

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func (p Person) SayHello() {
	fmt.Println("Hello, my name is", p.Name)
}

func testReflectMethod(p interface{}) {
	//p := Person{Name: "Alice", Age: 30}

	// 使用反射调用方法
	reflect.ValueOf(p).MethodByName("SayHello").Call([]reflect.Value{})
}

func main() {
	p := Person{Name: "Alice", Age: 30}

	// 使用反射调用方法
	//methodValue := reflect.ValueOf(p).MethodByName("SayHello")
	//if methodValue.IsValid() {
	//	methodValue.Call([]reflect.Value{})
	//} else {
	//	fmt.Println("Method not found")
	//}
	testReflectMethod(p)
}

通过反射获取值,修改值文章来源地址https://www.toymoban.com/news/detail-583604.html

package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Username string
	Email    string
}

type Admin struct {
	Title string
	User
}

func (u User) sayHello() {
	fmt.Println("Hello", u.Username)
}

func check(inter interface{}) {
	// v 就是断言传进来的类型是 User
	t := reflect.TypeOf(inter)
	v := reflect.ValueOf(inter)
	fmt.Println(t, v)
	// 调用方法

	// 根据字段名获取字段值
	u := v.FieldByName("User").FieldByName("Email")
	fmt.Println("value of u", u)
	// 根据索引获取字段值
	fmt.Println(v.FieldByIndex([]int{0}))
	fmt.Println(v.FieldByIndex([]int{1}))
	// 取索引 1 里面的 索引 1 的值
	fmt.Println("{1, 1}", v.FieldByIndex([]int{1, 1}))
	for i := 0; i < t.NumField(); i++ {
		fmt.Println(t.Field(i).Name, v.Field(i).Interface())
	}

	kind := t.Kind()
	// 判断是否是结构体
	if kind == reflect.Struct {
		fmt.Println("kind is struct")
	}

}

func changeValue(inter interface{}) {
	v := reflect.ValueOf(inter)
	e := v.Elem()
	e.FieldByName("Username").SetString("Rizky000")
	fmt.Println(inter)
}


func checkEnhanced(v interface{}) {
	// v 就是断言传进来的类型是 User
	switch v.(type) {
	case User:
		fmt.Println("User")
		v.(User).sayHello()
	case Admin:
		fmt.Println("Admin")
	default:
		fmt.Println("Unknown")
	}
}

func main() {
	u := User{
		Username: "Rizky",
		Email:    "@eyou.com",
	}

	//admin := Admin{
	//	Title: "Admin",
	//	User:  u,
	//}
	//check(admin)
	//checkEnhanced(u)
	//changeValue(&u)
	//check(u)
	//fmt.Println(u)
}

到了这里,关于go 笔记 十二章 断言 assertion 和 反射 reflect的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GO基础进阶篇 (十二)、反射

    Go语言中的反射是指在程序运行时检查程序的结构,比如变量的类型、方法的签名等。Go语言的反射包是reflect。通过反射,你可以动态地检查类型信息、获取字段和方法、调用方法等。 反射可以在运行时动态获取变量的各种信息,比如变量的类型、值等 如果是结构体,还可以

    2024年02月02日
    浏览(49)
  • Go语言入门记录:从channel的池应用、sync的Pool、benchmark、反射reflect、json处理、http、性能分析和一些编程习惯

    channel的一对一会阻塞,添加buffer不会阻塞。 buffered Channel实现对象池。 sync.Pool 的介绍。 获取时先去私有对象中获取,如果不存在就在相同Processor中的共享池中获取,如果还没有,则去其他Processor中去获取。 存放时,如果私有对象不存在,就放在私有对象中,如果存在就放在

    2024年02月10日
    浏览(50)
  • python笔记:第十二章文件

    位于自动导入的模块IO中,无需手动导入。 若文件不存在,则报错 只指定文件名的话,会得到一个可读文件对象。若想写入文件,必须通过添加参数来指出。 默认模式为 rt ,将把文件视为Unicode文本,自动执行解码和编码,且默认使用UTF-8编码。 可以使用参数 encodin

    2024年02月16日
    浏览(42)
  • 《C和指针》读书笔记(第十二章 使用结构和指针)

    纸上得来终觉浅,绝知此事要躬行 。前几章学习了结构体、联合体和指针的相关知识。本章就是对这些知识的综合应用。 书中是以 链表 作为实例的,严格意义上来说,链表属于 数据结构与算法 的相关内容,关于这方面的知识,想学习的同学推荐《大话数据结构》这本书。

    2024年02月12日
    浏览(39)
  • Java中的Reflection(反射)、暴力反射

    1.1 反射的出现背景 Java程序中,所有的对象都有两种类型: 编译时类型 和 运行时类型 ,而很多时候对象的编译时类型和运行时类型 不一致 。 例如: 如上 :某些变量或形参的声明类型是 Object 类型,但是程序却需要调用该对象运行时类型的方法,该方法不是Object中的方法

    2024年02月04日
    浏览(46)
  • 【C/C++】详解 assert() 断言(什么是assert? assert有什么作用?)

    目录 一、前言 二、什么是 assert ?   三、assert 的用法  四、assert 案例解析  五、assert 断言的使用原则 六、共勉        在编写程序过程中,尤其是调试代码时,往往需要一个提醒 代码漏洞/Bug 的小助手,以便于程序员及时修改和完善代码。那么 assert 就可以成为这个

    2024年04月13日
    浏览(36)
  • assert 是一个断言语句

            在 Python 中, assert  是一个断言语句,用于测试代码中的条件是否为真。它的语法如下:         其中, condition  是要测试的条件,如果条件为真( True ),则程序继续执行;如果条件为假( False ),则会触发  AssertionError  异常,并且可以选择性地提供一个

    2024年02月05日
    浏览(39)
  • Python断言(assert)

    Python实用教程_spiritx的博客-CSDN博客 Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。 断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系

    2024年02月09日
    浏览(36)
  • Java 之 assert (断言)

    我们知道C/C++语言中有断言的功能(assert)。在Java SE 1.4版本以后也增加了断言的特性。 断言是为了方便调试程序,并不是发布程序的组成部分。理解这一点是很关键的。 默认情况下,JVM是关闭断言的。因此如果想使用断言调试程序,需要手动打开断言功能。在命令行模式下运

    2024年02月14日
    浏览(36)
  • SpringBoot单元测试断言 assertions

    断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。JUnit 5 内置的断言可以分成如下几个类别: 1、简单断言 2、数组断言 通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等

    2024年02月05日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包