欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang程序進度條實現(xiàn)示例詳解

 更新時間:2022年08月29日 11:33:16   作者:jonylee  
這篇文章主要為大家介紹了golang程序?qū)崿F(xiàn)進度條示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

最近在工作中寫一個批處理腳本,令人抓狂的是每次都不知道腳本要跑到啥時候結(jié)束,于是想到給程序添加個進度條。

逛了一圈,沒找到特別趁手的輪子,本著有手就行的原則,今天簡單地給大家擼一個終端進度條。

原理

終端進度條打印的原理是通過輸入\r將光標位置移動到當前行的行首,重新打印一份進度信息。

如果是使用\n,則光標會另起一行打印信息。

上才藝

首先從核心功能出發(fā),進度條要告訴我的信息有

  • 一共要完成多少任務(wù)
  • 現(xiàn)在完成了多少任務(wù)
  • 到什么時候才能完成全部任務(wù)

根據(jù)上面的需求

畫了個大概的樣子長這樣 [█████████████████████████]100/100 [eta]16:33:39

抽象的用戶調(diào)用函數(shù)有3個

New()新建進度條實例 Done()推進進度條進展 Finish()完成進度條

是不是和sync.WaitGroup很像。

調(diào)用代碼

func main() {
	bar := progress.New(100)
	for i := 0; i < 100; i++ {
		time.Sleep(time.Second / 10)
		bar.Done(1)
	}
	bar.Finish()
}

所以根據(jù)用戶調(diào)用需求,首先定義進度條結(jié)構(gòu)體。

type Bar struct {
	total         int64         // 總進度
	current       int64         // 當前進度
	filler        string        // 進度填充字符
	filler_length int64         // 進度條長度
	time_format   string        // 進度條時間格式
	interval      time.Duration // 打印時間間隔
	begin         time.Time     // 任務(wù)開始時間
}

然后根據(jù)用戶調(diào)用的函數(shù),給出函數(shù)實現(xiàn),當然這里面加了一些函數(shù)參數(shù)可選項。

可以在初始化實例的時候自定義一些元素,比如填充字符,比如時間格式或者是每隔多少時間刷新一次進度條等等。

// New 新建進度條實例
func New(total int64, opts ...func(*Bar)) *Bar {
	bar := &Bar{
		total:         total,
		filler:        "█",
		filler_length: 25,
		time_format:   "15:04:05", // 2006-01-02T15:04:05
		interval:      time.Second,
		begin:         time.Now(),
	}
	for _, opt := range opts {
		opt(bar)
	}
	// 定時打印
	ticker := time.NewTicker(bar.interval)
	go func() {
		for bar.current < bar.total {
			fmt.Print(bar.get_progress_string())// 打印進度
			<-ticker.C
		}
	}()
	return bar
}
// Done 更新完成進度
func (bar *Bar) Done(i int64) {
	bar.current += i
}
// Finish 完成最后進度條
func (bar *Bar) Finish() {
	fmt.Println(bar.get_progress_string())
}
// WithFiller 設(shè)置進度條填充字符
func WithFiller(filler string) func(*Bar) {
	return func(bar *Bar) {
		if len(bar.filler) != 0 {
			bar.filler = filler
		}
	}
}

那么處理完了用戶怎么使用之后,我們就來開始處理怎么給用戶展示進度條效果。

要想根據(jù)進度填充不同的字符比例,先算進度百分比,長下面這樣子。

//get_percent 獲取進度百分比,區(qū)間0-100
func (bar *Bar) get_percent() int64 {
	return bar.current * 100 / bar.total
}

因為我們進度條并不需要那么精確,所有這里都用的是整數(shù)來處理,更方便一些,不用做各種類型轉(zhuǎn)換。

那么拿到百分比之后,就能根據(jù)進度條總長度來計算要填充多少個█。

接下來算任務(wù)什么時候完成,這里用的算法是,用當前完成了多少個任務(wù)和花了多少時間來估算總?cè)蝿?wù)數(shù)的要花費多少時間,得到預計什么時候完成,代碼是這樣子的:

//get_eta 獲取eta時間
func (bar *Bar) get_eta(now time.Time) string {
	eta := (now.Unix() - bar.begin.Unix()) * 100 / (bar.get_percent() + 1)
	return bar.begin.Add(time.Second * time.Duration(eta)).Format(bar.time_format)
}

最后,我們來處理下需要在控制臺打印的字符串,同時作為非核心需求,我們還想看批處理操作的速度,所以這里用QPS來表達我們整個任務(wù)處理的速度。

QPS表達任務(wù)處理速度

//get_progress_string 獲取打印控制臺字符串
func (bar *Bar) get_progress_string() string {
	fills := bar.get_percent() * bar.filler_length / 100
	for i := int64(0); i < bar.filler_length; i++ {
		switch {
		case i < fills:
			chunks[i] = bar.filler
		default:
			chunks[i] = " "
		}
	}
	now := time.Now()
	eta := bar.get_eta(now)
	qps := bar.current / (now.Unix() - bar.begin.Unix() + 1)
	return fmt.Sprintf("\r[%s]%d/%d [eta]%s [qps]%d ", strings.Join(chunks, ""), bar.current, bar.total, eta, qps)
}

最終呈現(xiàn)的效果 [█████████████████████████]100/100 [eta]16:33:39 [qps]9 

當然,為了更酷炫一點,同時還引入了emoji字符,能夠根據(jù)字符自適應(yīng)地調(diào)整顯示效果。

下面是項目github地址,供大家參考

https://github.com/jony-lee/go-progress-ba

知識點總結(jié)

下面是知識點總結(jié)

  • 使用\r來將控制臺光標定位到行首實現(xiàn)行內(nèi)進度條刷新。
  • 使用函數(shù)可選參數(shù)來實現(xiàn)用戶自定義設(shè)置。
  • 使用函數(shù)time.NewTicker()實現(xiàn)定時刷新控制臺進度條。

以上就是golang程序進度條實現(xiàn)示例詳解的詳細內(nèi)容,更多關(guān)于golang程序進度條的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入理解go sync.Waitgroup的使用

    深入理解go sync.Waitgroup的使用

    WaitGroup在go語言中,用于線程同步,本文主要介紹了深入理解go sync.Waitgroup的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Golang設(shè)計模式之責任鏈模式講解和代碼示例

    Golang設(shè)計模式之責任鏈模式講解和代碼示例

    責任鏈是一種行為設(shè)計模式, 允許你將請求沿著處理者鏈進行發(fā)送, 直至其中一個處理者對其進行處理,本文就詳細給大家介紹一下Golang 責任鏈模式,文中有詳細的代碼示例,需要的朋友可以參考下
    2023-06-06
  • SingleFlight模式的Go并發(fā)編程學習

    SingleFlight模式的Go并發(fā)編程學習

    這篇文章主要為大家介紹了SingleFlight模式的Go并發(fā)編程學習,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • Go導入不同目錄下包報錯的解決方法

    Go導入不同目錄下包報錯的解決方法

    包(package)是多個Go源碼的集合,是一種高級的代碼復用方案,下面這篇文章主要給大家介紹了關(guān)于Go導入不同目錄下包報錯的解決方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • go 判斷兩個 slice/struct/map 是否相等的實例

    go 判斷兩個 slice/struct/map 是否相等的實例

    這篇文章主要介紹了go 判斷兩個 slice/struct/map 是否相等的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go Java算法之Excel表列名稱示例詳解

    Go Java算法之Excel表列名稱示例詳解

    這篇文章主要為大家介紹了Go Java算法之Excel表列名稱示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Go?viper讀取配置文件的示例詳解

    Go?viper讀取配置文件的示例詳解

    這篇文章主要為大家詳細介紹了Go語言如何利用viper實現(xiàn)讀取配置文件,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下
    2023-08-08
  • Go中各種newreader和newbuffer的使用總結(jié)

    Go中各種newreader和newbuffer的使用總結(jié)

    這篇文章主要為大家詳細介紹了Go語言中各種newreader和newbuffer的使用的相關(guān)資料,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以了解下
    2023-11-11
  • Go語言正則表達式示例

    Go語言正則表達式示例

    這篇文章主要介紹了Go語言正則表達式,結(jié)合實例形式分析了Go語言正則表達式實現(xiàn)字符串的匹配、查找等相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01
  • golang常用庫之操作數(shù)據(jù)庫的orm框架-gorm基本使用詳解

    golang常用庫之操作數(shù)據(jù)庫的orm框架-gorm基本使用詳解

    這篇文章主要介紹了golang常用庫之操作數(shù)據(jù)庫的orm框架-gorm基本使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10

最新評論