<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    Go 泛型 filter 功能實(shí)現(xiàn)

    共 3077字,需瀏覽 7分鐘

     ·

    2021-10-17 11:53

    還不太清楚Go1.17泛型基本用法的同學(xué)可以看下站長(zhǎng)之前寫的Go泛型系列:提前掌握Go泛型的基本使用[1]正好看此文也可以簡(jiǎn)單復(fù)習(xí)一下。今天土撥鼠給大家介紹下泛型過(guò)濾(Filter)功能的小短文(參考Implementing a Generic Filter Function in Go[2])。例子也很簡(jiǎn)單,希望大家能從中有所收獲。

    功能實(shí)現(xiàn):過(guò)濾一下切片中符合條件的元素,并返回

    正常情況下的話土撥鼠會(huì)簡(jiǎn)單寫一下,一般都是作為一次性使用。

    簡(jiǎn)單版

    //?filter?過(guò)濾掉不符合條件的元素
    func?filter(items?[]interface{})?[]interface{}?{
    ????filteredItems?:=?[]interface{}{}
    ????for?index,?value?:=?range?items?{
    ????????//?過(guò)濾掉奇數(shù)
    ????????if?num.(int)%2?==?0?{
    ????????????filteredItems?=?append(filteredItems,?value)
    ????????}
    ????}
    ????return?filteredItems
    }

    顯然這樣寫太簡(jiǎn)單了,一點(diǎn)都不夠優(yōu)雅。條件函數(shù)的話這里可以考慮用閉包作為函數(shù)參數(shù)來(lái)稍微優(yōu)化一下。這樣就可以編寫各種花樣的過(guò)濾邏輯咯。

    優(yōu)化版

    //?filter?過(guò)濾掉不符合條件的元素
    func?filter(items?[]interface{},?fn?func(index?int,?item?interface{})?bool)?[]interface{}?{
    ????filteredItems?:=?[]interface{}{}
    ????for?index,?value?:=?range?items?{
    ????????if?fn(index,?value)?{
    ????????????filteredItems?=?append(filteredItems,?value)
    ????????}
    ????}
    ????return?filteredItems
    }

    func?main()?{
    ????var?nums?[]interface{}
    ????nums?=?append(nums,?1,?2,?3,?4,?5)
    ????evenNums?:=?filter(nums,?func(index?int,?num?interface{})?bool?{?return?num.(int)%2?==?0?})
    ????
    ????fmt.Printf("%d",?evenNums[0].(int)?+?2)
    }

    約束版

    為了使得類型使用更加清晰明了一些,咱們這里使用any類型(可不是隨便起的哦,可以參考類型參數(shù)提案中any的約束[3])來(lái)替代interface{}類型。修改如下:

    type?any?=?interface{}

    //?filter?過(guò)濾掉不符合條件的元素
    func?filter(items?[]any,?fn?func(index?int,?item?any)?bool)?[]any?{
    ????filteredItems?:=?[]any{}
    ????for?index,?value?:=?range?items?{
    ????????if?fn(index,?value)?{
    ????????????filteredItems?=?append(filteredItems,?value)
    ????????}
    ????}
    ????return?filteredItems
    }

    這里給大家講一下什么是約束?約束主要是確保泛型類型的元素始終滿足特定的接口類型。根據(jù) Go 的哲學(xué),必須在類型參數(shù)聲明旁邊添加約束。這個(gè)demo使用的是any類型等同于interface{},可以接受任意類型的。所以這里的約束作用就由閉包來(lái)做了。

    func?filter[T?SomeInterface](items?[]T?)

    大家也可以在go2goPlayground[4]進(jìn)行測(cè)試,最終demo如下:

    package?main

    import?(
    ???"fmt"
    )

    //?filter?過(guò)濾掉不符合條件的元素
    func?filter[T?any](items?[]T,?fn?func(item?T?"T?any")?bool)?[]T?{
    ????filteredItems?:=?[]T{}
    ????for?_,?value?:=?range?items?{
    ????????if?fn(value)?{
    ????????????filteredItems?=?append(filteredItems,?value)
    ????????}
    ????}
    ????return?filteredItems
    }

    func?main()?{
    ????nums?:=?[]int{1,?2,?3,?4,?5}
    ????evenNums?:=?filter(nums,?func(num?int)?bool?{?return?num%2?==?0?})
    ????fmt.Println(evenNums)
    }

    參考資料

    [1]

    Go泛型系列:提前掌握Go泛型的基本使用: https://polarisxu.studygolang.com/posts/go/generics/generics-basic

    [2]

    Implementing a Generic Filter Function in Go: https://preslav.me/2021/09/22/implementing-a-generic-filter-function-in-golang/

    [3]

    類型參數(shù)提案中any的約束: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#the-constraint

    [4]

    go2goPlayground: https://go2goplay.golang.org/

    [5]

    go: don't change the libraries in 1.18: https://github.com/golang/go/issues/48918

    [6]

    #45955-slices: new package to provide generic slice functions: https://github.com/golang/go/issues/45955

    [7]

    #48594-proposal: bytes: add Grow, Clip; maybe add bytes/strings Insert, Delete: https://github.com/golang/go/issues/48594





    推薦閱讀


    福利

    我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

    瀏覽 42
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    欧美性成人1819 | 国产精品三级片在线观看 | 青娱乐国产在线 | 人人搞人人摸 | 日韩人妻无码视频 |