GoLang构造函数

[TOC]

GoLang构造函数

具体代码位置 构造函数 我之前的的另一个学习项目

另一篇笔记 Golang学习笔记 中的构造函数和复合声明部分也有描述和简单的实例

写这个笔记的原因,是因为前一阵子过同事的goLang代码, 看到他写的构造函数深感无奈.所以在这里记一下,我之前的案例.

构造函数源码

代码案例1

1package taskrunner 2 3//runner对象 4type Runner struct { 5 Controller controlChan //Dispatcher和Executor的生产者和消费者互相交互信息 6 Error controlChan //告知程序是否关闭资源 7 Data dataChan //真正的交互数据 8 dataSize int //传输的数据大小 9 longLived bool //是否是长期存在的资源(不回执行close()回收资源) 10 Dispatcher fn //分配器(生产者) 11 Executor fn //执行者(消费者) 12} 13 14//创建启动任务,模拟构造函数 15func NewRunner(size int, longLived bool, d fn, e fn) *Runner { 16 17 return &Runner{ 18 Controller: make(chan string, 1), //要带buffer 19 Error: make(chan string, 1), 20 Data: make(chan interface{}, size), 21 longLived: longLived, 22 dataSize: size, 23 Dispatcher: d, 24 Executor: e, 25 } 26} 27 28//开始分配任务(常驻任务),长时间等待Controller channel和Data channel的数据来做处理 29func (r *Runner) startDispatch() { 30 31 //声明匿名函数 32 defer func() { 33 //判断是否是要常驻内存,不需要的话就关闭所有channel 34 if !r.longLived { 35 close(r.Controller) 36 close(r.Data) 37 close(r.Error) 38 } 39 }() //没有这里的()该函数不会自动执行 40 41 //死循环不断处理消费者和生产者的channel中的数据 42 for { 43 select { 44 //读取Controller的channel中的数据,判断是生产者还是消费者 45 case c := <-r.Controller: 46 //生产者 47 if c == READY_TO_DISPATCH { 48 //把传入的数据,放入到生产者的回调函数中,同时判断回调函数的处理结果 49 err := r.Dispatcher(r.Data) 50 if err != nil { 51 //回调函数执行出错,通过传参, 指定关闭 52 r.Error <- CLOSE 53 } else { 54 //通过传参,切换为消费者 55 r.Controller <- READY_TO_EXECUTE 56 } 57 } 58 59 //消费者 60 if c == READY_TO_EXECUTE { 61 //把传入的数据,放入到消费者的回调函数中,同时判断回调函数的处理结果 62 err := r.Executor(r.Data) 63 if err != nil { 64 //回调函数执行出错,通过传参,指定关闭 65 r.Error <- CLOSE 66 } else { 67 //通过传参,切换为生产者 68 r.Controller <- READY_TO_DISPATCH 69 } 70 } 71 //读取channel中需要关闭的资源 72 case e := <-r.Error: 73 if e == CLOSE { 74 return 75 } 76 default: 77 78 } 79 80 } 81} 82 83//启动生产者和消费者模型 84func (r *Runner) StartAll() { 85 //开启生产者和消费者模型,同时预制状态,否则进程会僵死 86 r.Controller <- READY_TO_DISPATCH 87 //启动生产者 88 r.startDispatch() 89} 90

代理案例2

1package taskrunner 2 3import "time" 4 5type Worker struct { 6 /** 7 *ticker只要定义完成,从此刻开始计时,不需要任何其他的操作,每隔固定时间都会触发。 8 *timer定时器,是到固定时间后会执行一次 9 *如果timer定时器要每隔间隔的时间执行,实现ticker的效果,使用 func (t *Timer) Reset(d Duration) bool 10 */ 11 ticker *time.Ticker 12 runner *Runner 13} 14 15//新建一个进程 16func NewWorker(interval time.Duration, r *Runner) *Worker { 17 return &Worker{ 18 //NewTicker 返回一个新的 Ticker,该 Ticker 包含一个通道字段,并会每隔时间段 d 就向该通道发送当时的时间。它会调 19 //整时间间隔或者丢弃 tick 信息以适应反应慢的接收者。如果d <= 0会触发panic。关闭该 Ticker 可 20 //以释放相关资源。 21 ticker: time.NewTicker(interval * time.Second), 22 runner: r, 23 } 24} 25 26func (w *Worker) startWorker() { 27 //这里不能用range 否则会出现误差 28 for { 29 select { 30 case <-w.ticker.C: 31 go w.runner.StartAll() 32 } 33 } 34} 35 36func Start() { 37 //start video file cleaning 38 r := NewRunner(3, true, VideoClearDispatcher, VideoClearExecutor) 39 w := NewWorker(3, r) 40 go w.startWorker() 41}

流程解读

从上面两个案例, 但从构造函数的设计上来看基本套路一致,同时可以显而易见的看出,构造函数的思路.

  1. 声明一个type(也有人习惯称其为类),假定名称为type A struct{}

  2. 为该type A struct{}准备几个方法func Get()和func Set()

  3. 声明一个独立的函数,假定为名称为NewTyepA(),

  4. 在NewTypeA()公共函数中返回, 实例化后的Type A struct的指针即可,

  5. 同时在NewTyeA()也可以为type A struct 指定各种初始化的操作

而后在其他文件中通过调用NewTypeA()即可调用TypeA中的所有方法

例如:

NewTypeA().Get()

就相当于:

1// 伪代码 2typeA.Get()
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )