go语言进阶003

本文详细介绍了Go语言中的并发编程模型CSP,包括select语句的工作原理和goroutine、channel的使用。同时,深入探讨了Go的反射机制,如何在运行时获取和操作对象的类型信息,以及在实际开发中的应用场景。通过示例展示了如何通过反射获取接口类型变量的值和类型。
摘要由CSDN通过智能技术生成

1、select

分支语句:if,switch,select
select类似switch
但是select语句会随机执行一个可运行的case
如果都不匹配,就看有没有default,如果没有就会阻塞

2、CSP并发编程模型

communicating Sequential Process:通信顺序进程。
作者自定义了,输入输出语句,用于process进程之间的通信,process被认为是需要输入驱动,会产生输出,来帮助其他的process消费。process可以是进程、线程、代码块。
!表示对一个process输入数据,
?表示输出
process <----> gproutine,并发执行的实体
channel,线程安全的,先进先出的特性

goroutine 是实际并发执行的实体,它底层是使用coroutine(协程)实现并发。coroutine是用户态线程。类似于greenthread
coroutine:
用户空间:避免内核态和用户态切换的成本
可以由语言和框架层进行调度
更小的栈空间允许创建大量的实例
goroutine:调度器
go并发模型:G-P-M模型

消息队列的解耦功能

3、go语句的反射reflect

反射是一种让程序,主要通过类型,理解其自身结构的一种能力。
在运行的时候,来获取这个对象的类型信息和内存结构
java中的反射,在运行状态中,对任何的类都能确认到所有属性和方法。对一个对象都能调用任一方法和属性,这种动态获取和调用的方式,就是java的反射机制

go:在运行时更新变量和检查他们的值,调用他们的方法。但是在编译时并不知道这些变量的具体类型。称为反射机制。
应用场景:
1、要写一个函数,但是不知道函数的参数类型。可能没约定好,也可能类型很多,并不能统一表示。
2、有时候需要根据某些条件决定调用哪个函数,比如根据用户输入来决定。这时候就需要对函数和函数的参数进行反射,在运行期间动态的执行函数。
go语言的gRPC也是通过反射实现的
go的空接口类似java中的object这个类

只有interface才有反射这一说

tty ,err := os.OpenFile("/dev/tty",os.O_TDWR,0)  // tty文件指针对象

var r io.Reader   // 接口
r = tty   // 将一个实际类型数据赋值给了一个接口类型的变量,会在接口类型变量记录下实际类型数据的信息,它的值,和它的类型。接口变量r的pair中记录:(tty,*os.File)且这个pair在接口变量连续赋值的过程中也是不变的

反射就是用来检测存储在这个接口变量内部pair信息的一种机制。
反射的目的就是在运行时能够动态获取一个接口变量的值和类型,进而进行其他的操作。
3步:
1:有一个接口类型的变量
2:转成reflect对象,type类型活着value类型
3:根据不同的情况调用不同的函数

/*
   通过反射可以获取一个接口类型变量的 类型和数值
*/
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var x float64 = 3.14
	fmt.Println("type ", reflect.TypeOf(x))
	fmt.Println("value ", reflect.ValueOf(x))

	v := reflect.ValueOf(x)
	fmt.Println("kind is float64", v.Kind() == reflect.Float64) // v.Kind()方法获取反射包获取的值的类型
	fmt.Println("type is ", v.Type())
	fmt.Println("value is ", v.Float())

}

变量的类型,静态类型,动态类型
通过反射来获取接口类型变量,得到反射对象,然后再获取接口类型变量

var A interface {}
A = 10
A = "String"
var M *int
A = M  A的值可以改变

/*
   通过反射可以获取一个接口类型变量的 类型和数值
*/
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var x float64 = 3.14
	value := reflect.ValueOf(x)   // 通过一个接口类型变量 --->  获取一个反射对象
	fmt.Println(value)

	converValue := value.Interface().(float64)  // 通过interface方法,点上已知类型就可以得到真实值了
	fmt.Println(converValue)

}
// 如果是指针,在最后反射对象转成接口类型变量float64的时候要加 * 
pointqq := value.Interface().( * float64)

Kind()有slice.map,pointer指针,struct,interface,string,Array,Function,int活着其他基本数据类型
定义一个结构体:type Person struct{}
它的Kind就是struct,他的type就是Person
NumField获取成员变量的个数
NumMethod获取方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值