最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言實(shí)現(xiàn)有規(guī)律的數(shù)字版本號(hào)的排序工具

 更新時(shí)間:2023年01月10日 08:28:14   作者:陳明勇  
這篇文章主要為大家詳細(xì)介紹了如何利用Go語(yǔ)言實(shí)現(xiàn)有規(guī)律的數(shù)字版本號(hào)的排序工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下

前言

在某些場(chǎng)景,我們可能需要對(duì)版本號(hào)進(jìn)行排序。版本號(hào)的形式有很多種,例如:

  • 1.0.0, 1.0.1.1, 2.0.1.1
  • v1.0.0, v1.10.1, v2.0
  • ······

而本文所介紹的版本號(hào)排序工具,是針對(duì)有規(guī)律的數(shù)字版本號(hào)如 1.0.0, 1, 2.15.0 這種形式。

創(chuàng)作解讀

版本號(hào)的大小比較與排序

版本號(hào)排序的前提,首先得比較兩個(gè)版本號(hào)的大小。由于版本號(hào)長(zhǎng)度可能不一致,所以需要額外做一些處理。對(duì)于版本號(hào)的比較,我的算法思路是:

1、以 . 為分隔符,將版本號(hào)的每段數(shù)字存到切片里,方便后續(xù)比較大小。例如 "1.0"["1", "0"]"1.0.1"["1", "0", "1"]。

firstVersions := strings.Split(versions[i], ".")
secondVersions := strings.Split(versions[j], ".")

2、由于兩個(gè)版本號(hào)的長(zhǎng)度可能不一致,因此需要做 填充0,統(tǒng)一長(zhǎng)度 的操作。所以第二步就是獲取兩個(gè)版本號(hào)中,最大長(zhǎng)度,然后對(duì)長(zhǎng)度最小的版本號(hào)切片,填充零,保持兩個(gè)版本號(hào)的長(zhǎng)度一致。例如第一步的兩個(gè)版本號(hào) ["1", "0"]、["1", "0", "1"],需要對(duì)第一個(gè)版本號(hào)填充一個(gè)零(填充之后的結(jié)果 → ["1", "0", "0"]),才能保持兩個(gè)版本號(hào)的長(zhǎng)度一致,方便后續(xù)比較。

// 0 填充
// 獲取最大長(zhǎng)度并向最小長(zhǎng)度的切片填充 "0",統(tǒng)一長(zhǎng)度
func getMaxAndFillZero(s1 *[]string, s2 *[]string) int {
    len1, len2 := len(*s1), len(*s2)
    if len1 > len2 {
        fillZero(s2, len1-len2)
        return len1
    }
    fillZero(s1, len2-len1)
    return len2
}

// 0 填充
func fillZero(s *[]string, size int) {
    for i := 0; i < size; i++ {
        *s = append(*s, "0")
    }
}

size 為最大長(zhǎng)度 - 最小長(zhǎng)度的值,也就是要填充 0 的個(gè)數(shù)。

3、遍歷切片,從前依次比較兩個(gè)版本號(hào)每段數(shù)字的大小。

如果第一個(gè)版本號(hào)的第一段數(shù)字大于或小于第二個(gè)版本號(hào)的第二段數(shù)字,則可以根據(jù)排序規(guī)則決定兩個(gè)版本號(hào)的先后位置。

如果相等,則比較下一段數(shù)字的大小,以此類(lèi)推。

for k := 0; k < maxLen; k++ {
    // 由于上面判斷了版本號(hào)的合法性,因此 error 可以忽略
    vi, _ := strconv.Atoi(firstVersions[k])
    vj, _ := strconv.Atoi(secondVersions[k])
    if vi < vj {
        if sortRule == DESC {
            // 降序排序
            // todo 交換操作
        }
        // 默認(rèn)升序排序,即使 sortRule 不是 ASC
        // todo 交換操作
    } else if vi > vj {
        // 降序排序
        if sortRule == DESC {
            // todo 交換操作
        }
        // 默認(rèn)升序排序,即使 sortRule 不是 ASC
        // todo 交換操作
    }
}

對(duì)字符串切片的排序,本工具使用的函數(shù)是 SliceStable(x any, less func(i, j int) bool),通過(guò)此函數(shù),可以自定義比較大小的規(guī)則。

sort.SliceStable(versions, func(i, j int) bool {
    firstVersions := strings.Split(versions[i], ".")
    secondVersions := strings.Split(versions[j], ".")
    // 判斷版本號(hào)格式的合法性
    isNormal(firstVersions)
    isNormal(secondVersions)
    // 獲取最大值并填充 "0", 統(tǒng)一長(zhǎng)度
    maxLen := getMaxAndFillZero(&firstVersions, &secondVersions)
    for k := 0; k < maxLen; k++ {
        // 由于上面判斷了版本號(hào)的合法性,因此 error 可以忽略
        vi, _ := strconv.Atoi(firstVersions[k])
        vj, _ := strconv.Atoi(secondVersions[k])
        if vi < vj {
            if sortRule == DESC {
                // 降序排序
                return false
            }
            // 默認(rèn)升序排序,即使 sortRule 不是 ASC
            return true
        } else if vi > vj {
            // 降序排序
            if sortRule == DESC {
                return true
            }
            // 默認(rèn)升序排序,即使 sortRule 不是 ASC
            return false
        }
    }
    return false
})

版本號(hào)的合法性校驗(yàn)

由于本工具處理的版本號(hào)是有規(guī)律的數(shù)字版本號(hào),如果版本號(hào)包含字母或其他特殊字符,會(huì)影響到排序的進(jìn)行,因此需要提前對(duì)版本號(hào)進(jìn)行合法性的校驗(yàn)。

// 判斷版本號(hào)的格式是否合法
func isNormal(versions []string) {
   for _, v := range versions {
      for _, r := range []rune(v) {
         if !unicode.IsNumber(r) {
            panic(errors.New("版本號(hào)格式錯(cuò)誤:" + string(r)))
         }
      }
   }
}

遍歷每段版本號(hào),然后對(duì)每段版本號(hào)的字符進(jìn)行遍歷,判斷是否是數(shù)字,如果不是,則 panic 掉,結(jié)束排序。

錯(cuò)誤處理

由于版本號(hào)的不合法性,可能會(huì)程序運(yùn)行的過(guò)程中產(chǎn)生錯(cuò)誤。因此,有必要人工捕獲錯(cuò)誤,提高工具的健壯性。

版本號(hào)排序函數(shù)提供一個(gè) error 的返回值,用于判斷是否產(chǎn)生錯(cuò)誤。錯(cuò)誤的捕獲邏輯如下:

defer func() {
   if r := recover(); r != nil {
      if er, ok := r.(error); ok {
         err = er
      } else {
         err = errors.New("")
         fmt.Println("未知錯(cuò)誤: ")
         fmt.Println(r)
      }
   }
}()

捕獲版本號(hào)的合法性校驗(yàn)時(shí)主動(dòng) panic 的錯(cuò)誤,并結(jié)束排序。

總結(jié)

  • 本工具實(shí)現(xiàn)了對(duì)有規(guī)律的數(shù)字版本號(hào)集合進(jìn)行排序。
  • 在排序的過(guò)程中,由于版本號(hào)的長(zhǎng)度可能不一致,因此執(zhí)行填充 0 操作,統(tǒng)一長(zhǎng)度,再進(jìn)行版本號(hào)的大小比較;
  • 除此之外,還對(duì)版本號(hào)的合法性做了校驗(yàn),捕獲可預(yù)知和不可預(yù)知的 panic 錯(cuò)誤,提高了工具的健壯性。
  • 經(jīng)測(cè)試,核心功能已實(shí)現(xiàn),但有些地方還能改進(jìn),后續(xù)會(huì)對(duì)代碼進(jìn)行優(yōu)化。

到此這篇關(guān)于Go語(yǔ)言實(shí)現(xiàn)有規(guī)律的數(shù)字版本號(hào)的排序工具的文章就介紹到這了,更多相關(guān)Go語(yǔ)言排序工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在Golang中正確的修改HTTPRequest的Host的操作方法

    在Golang中正確的修改HTTPRequest的Host的操作方法

    我們工作中經(jīng)常需要通過(guò)HTTP請(qǐng)求Server的服務(wù),比如腳本批量請(qǐng)求接口跑數(shù)據(jù),由于一些網(wǎng)關(guān)策略,部分Server會(huì)要求請(qǐng)求中Header里面附帶Host參數(shù),所以本文給大家介紹了如何在Golang中正確的修改HTTPRequest的Host,需要的朋友可以參考下
    2023-12-12
  • Go?select使用與底層原理講解

    Go?select使用與底層原理講解

    這篇文章主要介紹了Go?select使用與底層原理講解,select是Go提供的IO多路復(fù)用機(jī)制,可以用多個(gè)cas同時(shí)監(jiān)聽(tīng)多個(gè)channl的讀寫(xiě)狀態(tài),相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • Go語(yǔ)言中的函數(shù)式編程實(shí)踐

    Go語(yǔ)言中的函數(shù)式編程實(shí)踐

    這篇文章主要介紹了Go語(yǔ)言中的函數(shù)式編程實(shí)踐,主要講解Go語(yǔ)言中的函數(shù)式編程概念和使用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Go設(shè)計(jì)模式之模板方法模式講解和代碼示例

    Go設(shè)計(jì)模式之模板方法模式講解和代碼示例

    模版方法是一種行為設(shè)計(jì)模式, 它在基類(lèi)中定義了一個(gè)算法的框架, 允許子類(lèi)在不修改結(jié)構(gòu)的情況下重寫(xiě)算法的特定步驟,本文將通過(guò)代碼示例給大家詳細(xì)的介紹一下Go模板方法模式,需要的朋友可以參考下
    2023-08-08
  • Golang 并發(fā)讀寫(xiě)鎖的具體實(shí)現(xiàn)

    Golang 并發(fā)讀寫(xiě)鎖的具體實(shí)現(xiàn)

    Go語(yǔ)言中的sync.RWMutex提供了讀寫(xiě)鎖機(jī)制,允許多個(gè)協(xié)程并發(fā)讀取共享資源,但在寫(xiě)操作時(shí)保持獨(dú)占性,本文主要介紹了Golang 并發(fā)讀寫(xiě)鎖的具體實(shí)現(xiàn),感興趣的可以了解一下
    2025-02-02
  • go語(yǔ)言中int和byte轉(zhuǎn)換方式

    go語(yǔ)言中int和byte轉(zhuǎn)換方式

    這篇文章主要介紹了go語(yǔ)言中int和byte轉(zhuǎn)換方式,需要的朋友可以參考下
    2018-11-11
  • Go語(yǔ)言自定義linter靜態(tài)檢查工具

    Go語(yǔ)言自定義linter靜態(tài)檢查工具

    這篇文章主要介紹了Go語(yǔ)言自定義linter靜態(tài)檢查工具,Go語(yǔ)言是一門(mén)編譯型語(yǔ)言,編譯器將高級(jí)語(yǔ)言翻譯成機(jī)器語(yǔ)言,會(huì)先對(duì)源代碼做詞法分析,詞法分析是將字符序列轉(zhuǎn)換為T(mén)oken序列的過(guò)程,文章詳細(xì)介紹需要的小伙伴可以參考一下
    2022-05-05
  • Go生成base64圖片驗(yàn)證碼實(shí)例(超詳細(xì)工具類(lèi))

    Go生成base64圖片驗(yàn)證碼實(shí)例(超詳細(xì)工具類(lèi))

    這段時(shí)間需要使用圖片驗(yàn)證碼庫(kù),下面這篇文章主要給大家介紹了關(guān)于Go生成base64圖片驗(yàn)證碼的相關(guān)資料,文中給出了詳細(xì)的實(shí)例代碼,需要的朋友可以參考下
    2023-06-06
  • golang中的jwt使用教程流程分析

    golang中的jwt使用教程流程分析

    這篇文章主要介紹了golang中的jwt使用教程,接下來(lái)我們需要講解一下Claims該結(jié)構(gòu)體存儲(chǔ)了token字符串的超時(shí)時(shí)間等信息以及在解析時(shí)的Token校驗(yàn)工作,需要的朋友可以參考下
    2023-05-05
  • 一文了解Go語(yǔ)言io.Copy函數(shù)

    一文了解Go語(yǔ)言io.Copy函數(shù)

    這篇文章主要為大家介紹了Go語(yǔ)言io.Copy函數(shù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評(píng)論

汉川市| 乳源| 沁水县| 德江县| 黑龙江省| 新田县| 丰原市| 黎平县| 澄江县| 邻水| 高要市| 咸丰县| 类乌齐县| 桃源县| 石棉县| 板桥市| 中方县| 义马市| 灵台县| 明星| 合江县| 凭祥市| 密云县| 晋州市| 陵川县| 昆明市| 秭归县| 昌吉市| 军事| 县级市| 江城| 宕昌县| 南乐县| 高淳县| 赣州市| 阿荣旗| 龙山县| 吉隆县| 沙坪坝区| 玉环县| 德兴市|