专栏首页有趣的django9.Go-反射、日志和线程休眠

9.Go-反射、日志和线程休眠

9.1反射

在Go语言标准库中reflect包提供了运行时反射,程序运行过程中动态操作结构体

当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射

反射还可以用作判断变量类型

整个reflect包中最重要的两个类型

  • reflect.Type类型
  • reflect.Value值

获取到Type和Value的函数

  • reflect.TypeOf(interface{})返回type
  • reflect.ValueOf(interface{})返回值Value

  (1)获取变量属性和值

//Learn_Go/main.go
package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := 1.5
	fmt.Println(reflect.TypeOf(a))       //float64
	fmt.Println(reflect.ValueOf(a))      //1.5
}

 (2)获取结构体属性的值

//Learn_Go/main.go
package main

import (
	"fmt"
	"reflect"
)

type People struct {
	name string
	address string
}
func main() {
	peo := People{"derek","guangdong"}
	v := reflect.ValueOf(peo)
	//有多少个字段
	fmt.Println(v.NumField())                  //2
	//根据索引获取字段值
	fmt.Println(v.FieldByIndex([]int {0}))     //derek
	
	content := "address"
	fmt.Println(v.FieldByName(content))       //guangdong
}

 (3)设置结构体属性的值

反射时获取peo的地址,Elem()获取指针指向地址的封装

//Learn_Go/main.go
package main

import (
	"fmt"
	"reflect"
)

type People struct {
	Name string
	Address string
}
func main() {
	content := "Name"
	peo := new(People)
	//Elem()获取指针对应元素的值
	v := reflect.ValueOf(peo).Elem()
	//CanSet():判断值有没有被设置,有设置:True,没有设置:false
	fmt.Println(v.FieldByName(content).CanSet())

	//需要修改属性的内容时,要求结构体中属性名首字母大写才可以设置
	v.FieldByName(content).SetString("alice")
	v.FieldByName("Address").SetString("beijing")
	fmt.Println(peo)       //&{alice beijing}
}

 (4)结构体支持标记(tag),标记通常都是通过反射技术获取到 

//Learn_Go/main.go
package main

import (
	"fmt"
	"reflect"
)

type People struct {
	Name string `xml:"name"`
	Address string
}
func main() {
	t := reflect.TypeOf(People{})
	fmt.Println(t.FieldByName("Name"))      //{Name  string xml:"name" 0 [0] false} true
	name,_ := t.FieldByName("Name")
	fmt.Println(name.Tag)                  //xml:"name"
	fmt.Println(name.Tag.Get("xml"))       //name
}

9.2.日志

有三种级别日志输出

  • Print() 输出日志信息
  • Panic()打印日志信息,并处罚panic,日志信息为Panic信息
  • Fatal()打印日志信息后调用os.Exit(0)

所有日志信息打印时都带有时间,且颜色为红色,输出日志信息到文件中

//Learn_Go/main.go
package main

import (
	"log"
	"os"
)

func main() {
	f,_ := os.OpenFile("D:/golog.log",os.O_APPEND|os.O_CREATE,0777)
	logger := log.New(f,"[Info]",log.Ltime)         //"[Info]":prefix string
	logger.Println("打印日志信息")                  //[Info]22:13:59 打印日志信息
}

9.3.线程休眠和延迟执行

(1)线程休眠 

Go语言中main()函数为主线程(协程),程序是从上向下执行的

可以通过time包下的Sleep(n)让程序阻塞多少纳秒

//Learn_Go/main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("111")
	time.Sleep(2e9)     //2e9 相当于2秒
	fmt.Println("222")
}

(2)延迟执行

延迟指定时间后执行一次,但是需要注意在触发时程序没有结束

//Learn_Go/main.go
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("程序开始")
	time.AfterFunc(3e9, func() {
		fmt.Println("延迟执行")
	})
	time.Sleep(4e9)    //必须阻塞4s,要不主程序执行完直接退出,不会执行“延迟执行”的代码
	fmt.Println("程序结束")
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 代码写成这样,老板把我开除了,最让人感到无可奈何的代码,你可千万别这么写!

    后面有人挖出来这段神逻辑,大家真是哭晕在厕所了,还好,抢购买手机这种我从来不参加。。

    乔戈里
  • Go 并发实战--协程浅析 一

    在说go协程之前,先对比看一下进程&线程&协程这几个基础的概念。 进程是指一段程序的执行过程,具有自己的地址空间(包括文本区域(text region)、数据...

    邹志全
  • 几个预防并发搞垮下游服务的方法

    上一篇文章 我用休眠做并发控制,搞垮了下游服务 发出去后得到不少网友的回应,有人问自己平时用的方案行不行,有人建议借鉴TCP的拥塞控制策略,动态地调整发起的并发...

    KevinYan
  • Android耗电量线下监控: Battery Historian

    Android 框架层通过一个名为 batterystats 的系统服务,电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。 ...

    小木箱
  • CTO 说了,如果发现谁用 kill -9 关闭程序就开除

    kill可将指定的信息送至程序。预设的信息为SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除程序。程序或...

    架构师修炼
  • 还在使用kill -9 pid结束spring boot项目吗?那你已经落伍了!

    kill可将指定的信息送至程序。预设的信息为SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除程序。程序或...

    肉眼品世界
  • 电费太贵、基站休眠,运营商何时才能赚到5G的钱?

    “在 5G 建网初期,5G 基站规模已处于加速增长的状态,而用户规模还处于起步状态,5G 基站能耗引起的运营成本与收入之间的冲突,是网络维护人员需要面对和解决的...

    深度学习与Python
  • 代码写成这样,老夫无可奈何!

    今天,栈长就来总结一下我遇到过的一些神逻辑代码,不一定很全,但我真心写不出,真心让我自叹不如啊!

    测试开发社区
  • java多线程系列_线程的生命周期(4)

    与人有生老病死一样,线程也同样要经历开始(等待)、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。下面给出了Thread类中...

    Hongten
  • Handler中的消息屏障

    Handler中的消息队列如上图所示,是一个单链表,各个消息按照执行时间先后排列,消息类型分为三种:普通消息(normal)、屏障消息(barrier)、异步消...

    码农帮派
  • nodejs php go语言了解

    1、Nodejs 1) 简单的说 Node.js 就是运行在服务端的 JavaScript。 2) Node.js 是一个基于Chrome JavaScript...

    李海彬
  • 线程

    https://www.cnblogs.com/wihainan/p/4765862.html

    大学里的混子
  • Python多线程thread及模块使用实例

    线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多...

    砸漏
  • 《go 语言程序设计》读书笔记(六)Goroutine与系统线程的区别

    每一个OS线程都有一个固定大小的内存块(一般会是2MB)来做栈,这个栈会用来存储当前正在被调用或挂起(指在调用其它函数时)的函数的内部变量。这个固定大小的栈同时...

    KevinYan
  • Go语言调度器之盗取goroutine(17)

    本文是《Go语言调度器源代码情景分析》系列的第17篇,也是第三章《Goroutine调度策略》的第2小节。

    阿波张
  • 线程

    在创建线程时,必须要建立一个Thread类的或其子类的实例。因此,我们不难想到在调用start方法之前通过线程类的构造方法将数据传入线程。并将传入的数据使用类变...

    大学里的混子
  • 多图详解Go的互斥锁Mutex

    在Go的1.9版本中,为了解决等待中的 goroutine 可能会一直获取不到锁,增加了饥饿模式,让锁变得更公平,不公平的等待时间限制在 1 毫秒。

    luozhiyun
  • 黑群晖常见问题集锦

    答:群晖系统跟Windows不同,Windows有个盘要当成系统盘,而群晖会在每个硬盘上自动安装系统。每个硬盘?对,没错,就是每个硬盘。比如你是6盘位,接了6个...

    风吹屁屁凉
  • 忠于职守 —— sysmon 线程到底做了什么?(九)

    在 runtime.main() 函数中,执行 runtime_init() 前,会启动一个 sysmon 的监控线程,执行后台监控任务:

    梦醒人间

扫码关注云+社区

领取腾讯云代金券