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

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

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

前言

在某些場景,我們可能需要對版本號進行排序。版本號的形式有很多種,例如:

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

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

創(chuàng)作解讀

版本號的大小比較與排序

版本號排序的前提,首先得比較兩個版本號的大小。由于版本號長度可能不一致,所以需要額外做一些處理。對于版本號的比較,我的算法思路是:

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

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

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

// 0 填充
// 獲取最大長度并向最小長度的切片填充 "0",統(tǒ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 為最大長度 - 最小長度的值,也就是要填充 0 的個數(shù)。

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

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

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

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

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

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

版本號的合法性校驗

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

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

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

錯誤處理

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

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

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

捕獲版本號的合法性校驗時主動 panic 的錯誤,并結(jié)束排序。

總結(jié)

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

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

相關(guān)文章

  • Gin+Gorm實現(xiàn)CRUD的實戰(zhàn)

    Gin+Gorm實現(xiàn)CRUD的實戰(zhàn)

    本文主要介紹了Gin+Gorm實現(xiàn)CRUD的實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • go 對象池化組件 bytebufferpool使用詳解

    go 對象池化組件 bytebufferpool使用詳解

    這篇文章主要為大家介紹了go 對象池化組件 bytebufferpool使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Go語言學習之context包的用法詳解

    Go語言學習之context包的用法詳解

    日常Go開發(fā)中,Context包是用的最多的一個了,幾乎所有函數(shù)的第一個參數(shù)都是ctx,那么我們?yōu)槭裁匆獋鬟fContext呢,Context又有哪些用法,底層實現(xiàn)是如何呢?相信你也一定會有探索的欲望,那么就跟著本篇文章,一起來學習吧
    2022-10-10
  • golang解析json數(shù)據(jù)的4種方法總結(jié)

    golang解析json數(shù)據(jù)的4種方法總結(jié)

    在日常工作中每一名開發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • Go Java算法之同構(gòu)字符串示例詳解

    Go Java算法之同構(gòu)字符串示例詳解

    這篇文章主要為大家介紹了Go Java算法之同構(gòu)字符串示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Go 如何使用原始套接字捕獲網(wǎng)卡流量

    Go 如何使用原始套接字捕獲網(wǎng)卡流量

    為了減少對環(huán)境的依賴可以使用原始套接字捕獲網(wǎng)卡流量,然后使用?gopacket?的協(xié)議解析功能,這樣就省去了解析這部分的工作量,正確性也可以得到保證,同時 CGO 也可以關(guān)閉,這篇文章主要介紹了Go 使用原始套接字捕獲網(wǎng)卡流量,需要的朋友可以參考下
    2024-07-07
  • 300行代碼實現(xiàn)go語言即時通訊聊天室

    300行代碼實現(xiàn)go語言即時通訊聊天室

    本文主要介紹了300行代碼實現(xiàn)go語言即時通訊聊天室,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • 詳解Golang使用MongoDB通用操作

    詳解Golang使用MongoDB通用操作

    這篇文章主要介紹了詳解Golang使用MongoDB通用操作,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • golang elasticsearch Client的使用詳解

    golang elasticsearch Client的使用詳解

    這篇文章主要介紹了golang elasticsearch Client的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang?PHP?數(shù)據(jù)綁定示例分析

    Golang?PHP?數(shù)據(jù)綁定示例分析

    這篇文章主要為大家介紹了Golang?PHP?數(shù)據(jù)綁定示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08

最新評論