反射的快速入门(2)|学习笔记

简介: 快速学习反射的快速入门(2)

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:反射的快速入门(2)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9769


反射的快速入门(2)

 

内容介绍:

一、案例一

二、反射注意事项和细节说明

三、常量介绍

四、常量使用注意事项

 

一、案例一

请编写一个案例,演示对(结构体类型、interface{l}、reflect.value)进行反射的基本操作。

这节继续演示对结构体进行操作的案例

继续在原代码上添加:

fun reflectTest01(b interface{}){} 下输入

//专门演示反射[对结构体的反射]

fun reflectTest02(b interface{}){}

type Student struct { //首先需要先声明一个结构体例 type

Name string

Age int

}

然后在 func main() {}中继续输入

//1.先定义一个 int

var num int = 100

ref1ectTest02(num)

//2.定义一个 Student 的实例

stu := Student{

Name : “tom”,

Age : 20,

}

之后进行的操作都可以在案例1的代码基础上修改,rTyp 的代码不需要改,之后删除掉

n2 := 2+ rVal.Int()

fmt.Println(“n2=”, n2)

后面的代码将 rVal 转成 interface{}接口的代码不变

下一步是将接口通过断言转成需要的类型,删除掉

num2 := iV.(int) 重新转成结构体,注释掉 fmt.Println(“num2=”,num2)

先来试着打印结果,直接输出 iV,观察它是什么类型,因为 rVal 本身就是由结构体反射过来,所以在输出时会发现如下现象:

先在 iV:= rVal.Interface() 下输入

fmt.Printf(“iV=%v iV=%T”, iV, iV)

试着运行结果,接着在 func main(){} 中继续输入 reflectTest01(stu),将 Student 传入。现在操作就是将学生这个结构体传给了

代码如下:

func ref1ectTesto2(b interface[){

//通过反射获取的传入的变量的 type , kind 值

//1.先获取到 reflect.Type

rTyp := reflect.Typeof(b)

fmt.Print1n( "rType=", rTyp)

//2.获取到 reflect.value

rval := reflect.valueof(b)

//下面我们将 rval 转成 interface{}iv := rva1.Interface()

fmt.Printf( "iv=%v iv type=%T\n", iV,iV)

//将 interface{} 通过断言转成需要的类型

}

写完之后我们来掉它,用 ref1ectTest02(stu)。然后将 var num int = 100 ref1ectTest02(num)注销。然后运行以下。我们发现它的类型是 main.Student。但是根本就把 Name 取不出来,也就是为什么将 interface{} 通过断言转成需要的类型。

fmt.Printf("iv=%v iv type=%T name=%v\n", iv, iv,iv.Name)

这样就会报错。我们要明确反射的本质是运行时的,在编译阶段是被有办法确定iV是什么,因此编译器在 iV.name 这里过不去。所以必须要将 interface{} 通过断言转成需要的类型。

我们这里可以用:

stu, ok := iv.(student)

这里,我们就简单使用了一带检测的类型断言。

同学们可以使用swtich的断言形式来做的更加的灵活。

然后我们进行判断,把整个字段取出来,代码如下:

if ok {

fmt.Printf("stu. Name=%v\n", stu.Name)

}  //这个时候就可以取到 name 了

这时候打印出的内容就是:

rType= main.Student

iv=iu t ype =main.Student

Stu.Name=tom

然后要进行获取变量对应的 Kind。

第一种方式:rVal.Kind()

Kind1 := rVal.Kind()

第二种方式:rTyp.Kind()

kind2 := rTyp.Kind()

fmt.PrintfC"kind =%v kind=%v\n", kind1,kind2)

输出的结果为:
rType=main.Student

kind = struct kind = struct

iv =iv type=main.Student

Stu.Name=tom

我们可以看到两个 kind 都是 struct


二、反射注意事项和细节说明

1. reflect.Value.Kind 获取变量的类别,返回的是一个常量(看手册)

Kind 有两种方式可以拿到,第一种就是通过反射 Value 类型,这里面本身就提供了一种方法 Kind。Kind 返回v持有的值的分类,如果v是 Value 零值,返回值为Invalid。这里的 kind 就是个常量。

image.png

 

三、常量介绍

(一)常量使用 const 修改

(二)常量在定义的时候,必须初始化

(三)常量不能修改

(四)常量只能修饰 bool、数值类型(int,float系列)、string 类型,语法: const identifier [type] = value

我们举个例子:创建一个 main.go

package main

import ("fmt")

func main() {

var num int

const tax int

fmt.Print1n(num,tax)

}

此时会报错:没有一个表达式在后面,必须给他一个值所以要把 const tax int 变成const tax int = 0,所以常量在声明的时候必须赋值。

如果在 var num int 后面加一个 num = 90,这个是可以的,但是在 const tax int = 0 后面加一个 tax = 10,会报错:不能够辅助给 tax,所以常量是不能修改的。

举例说明,看看下面的写法是否正确:

const name = "tom"  //ok

const tax float64 = 0.8  //ok

const a int  //error没有进行初始化

const b = 9 / 3  //ok

会输出一个3,但是把9改成 num 就会报错,在编译的时候必须要确定b是多少 num 就不是常量,所以会报错。

const c = getVal()  //error

 

四、常量使用注意事项

(一)比较简介的写法

func main() {

const (

a =1

b = 2

)

fmt.Print1n(a,b)

}

(二)还有一种专业的写法

func main() {

cont (

a = iota

b

c

)

fmt.Print1n(a,b,c)l/e,1,2

表示给a赋值为0,b在a的基础上+1,c在b的基础上+1,这种写法就比较专业了。

(三)Golang 中没有常量名必须字母大写的规范比如 TAX_RATE,        比如:

image.png

(四)仍然通过首字母的大小写来控制常量的访问范围

相关文章
|
6月前
|
Java
Java反射课程教程
Java反射课程教程
36 0
|
SQL 监控 Java
魔法反射--java反射进阶(实战篇)
相信很多人在初学反射的时候也都会有这个想法(我就不相信就只有我一个人这么蠢!!) 大多数人不了解反射的原因并不是不了解, 而是不知道它到底能用来干什么 今天就来为大家分享一下反射的用法
85 0
|
Java
19 接口快速入门
接口就是把给出的一些未实现的方法,封装到一起;某个类需要实现接口的时候再重写这些方法
91 0
|
网络协议 测试技术 Go
反射的快速入门(1)|学习笔记
快速学习反射的快速入门(1)
反射的快速入门(1)|学习笔记
|
网络协议 测试技术 Go
接口介绍和快速入门|学习笔记
快速学习接口介绍和快速入门
接口介绍和快速入门|学习笔记
|
网络协议 Java 测试技术
继承快速入门应用实例|学习笔记
快速学习继承快速入门应用实例
继承快速入门应用实例|学习笔记
|
Scala 开发者
伴生对象的快速入门|学习笔记
快速学习伴生对象的快速入门。
|
Java Scala 开发者
函数基本介绍和快速入门|学习笔记
快速学习函数基本介绍和快速入门。
109 0
|
机器学习/深度学习 JSON 网络协议
反射的最佳实践(1) | 学习笔记
快速学习反射的最佳实践(1)