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

Golang Copier入門到入坑探究

 更新時間:2022年11月18日 15:44:47   作者:小白要生發(fā)  
這篇文章主要為大家介紹了Golang Copier入門到入坑探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

github: https://github.com/jinzhu/copier

由于 golang 沒有對復(fù)雜結(jié)構(gòu)體的 clone 方法,所以,就需要有 copier 這樣的工具庫。

它看起來很簡單,但實際使用中,有些“坑”還是要注意!

本文:

入門為輔,探“坑”為主,

看完再劃走,CS我沒有。

安裝

go get github.com/jinzhu/copier

快速入門

好的,來一段代碼快速了解 copier

package main
import (
    "fmt"
    "github.com/jinzhu/copier"
)
type SC struct {
    C uint8
}
type M1 struct {
    A int
    W string
    S *SC
}
func main() {
    var src = M1{12, "Hello", &SC{32}}
    var dst = M1{}
    fmt.Printf("before copy src %+v\tdst %+v\n", src, dst)
    copier.Copy(&dst, src)
    fmt.Printf("after  copy src %+v\tdst %+v\n", src, dst)
}

輸出:

before copy src {A:12 W:Hello S:0xc00017f550}   dst {A:0 W: S:<nil>}
after  copy src {A:12 W:Hello S:0xc00017f550}   dst {A:12 W:Hello S:0xc00017f618}

好的,看到這,你就已掌握了 copier 80%的功能了。先別著急劃走,接下來還是踩坑記錄。

本文代碼運行輸出內(nèi)容是基于 github.com/jinzhu/copier@v0.3.5 和 go1.16.1 darwin/amd64 環(huán)境演示的結(jié)果。

入坑

package main
import (
    "fmt"
    "github.com/davecgh/go-spew/spew"
    "github.com/jinzhu/copier"
)
type SC struct {
    C uint8
}
type Map1 struct {
    M map[string]int32
    A []int32
    C *SC
}
func main() {
    var src = Map1{map[string]int32{"C:": 3, "d": 4}, []int32{9, 8}, &SC{32}}
    var dst1 = Map1{}
    spew.Printf("before src %+v\t\tdst %+v\n", src, dst1)
    copier.Copy(&dst1, src)
    dst1.M["F"] = 5
    dst1.M["g"] = 6
    dst1.A[0] = 7
    dst1.C.C = 27
    spew.Printf("after  src %+v\tdst %+v\n", src, dst1)
}

以上代碼運行后會輸出:

before src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:32}}          dst {M:<nil> A:<nil> C:<nil>}

befre 那一行代碼如上?? , after 那一行會輸出什么呢?

1. after  src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:27}}  dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
2. after  src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:32}}  dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
3. after  src {M:map[C::3 d:4] A:[7 8] C:<*>(0xc00012a1e8){C:32}}  dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
4. after  src {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a1e8){C:32}}  dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
5. after  src {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a1e8){C:27}}  dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}

答案是: var a = int(759 / 6 / 31.5)

為了避免不小心看了答案,請計算 759 / 6 / 31.5 得出的值四舍五入便是。

再探坑出坑

我看其他同學(xué)使用 copier 也是像上面那樣——copier.Copy($dst, src), 當(dāng)然啦,也不排除我!它仿佛就是一把小巧精悍的小刀。一個簡單的函數(shù)調(diào)用,就完成了它的使命。

然而,它其實是把多功能刀,我都還沒有打開它的—— option。

上面的問題就是,我 Copy 后,對值的改動,影響了另一個值的 map,那么這個時候,就需要進(jìn)行深 copy。接下來引入 copier 的 option

package main
import (
    "fmt"
    "github.com/davecgh/go-spew/spew"
    "github.com/jinzhu/copier"
)
type SC struct {
    C uint8
}
type Map1 struct {
    M map[string]int32
    A []int32
    C *SC
}
func main() {
    var src = Map1{map[string]int32{"C:": 3, "d": 4}, []int32{9, 8}, &SC{32}}
    var dst1 = Map1{}
    spew.Printf("before src %+v\t\tdst %+v\n", src, dst1)
    copier.CopyWithOption(&dst1, src, copier.Option{DeepCopy: true})   // 這里!
    dst1.M["F"] = 5
    dst1.M["g"] = 6
    dst1.A[0] = 7
    dst1.C.C = 27
    spew.Printf("after  src %+v\tdst %+v\n", src, dst1)
}

好的,這樣copy之后,對新變量的改動,不會傳遞會原變量改動了。

再盤一盤坑

package main
import (
    "fmt"
    "github.com/davecgh/go-spew/spew"
    "github.com/jinzhu/copier"
)
type ArrTC struct {
    Name [2]string
    C    *ArrTC
}
type ArrT struct {
    A  [3]int32
    S  []int32
    E  []int32
    C  string
    V  string
    M map[string]int32
    AC ArrTC
    s bool
}
func main() {
    var src = ArrT{
        [3]int32{9, 10, 0},
        []int32{12, 0},
        []int32{},
        "",
        "val",
        map[string]int32{"A:": 1, "b": 0},
        ArrTC{},
        true,
    }
    var dst = ArrT{
        [3]int32{1, 2, 3},
        []int32{4, 5, 6, 7},
        []int32{9, 10},
        "char",
        "ha",
        map[string]int32{"C:": 3, "b": 4, ".": 0},
        ArrTC{[2]string{"Y", "Z"}, nil},
        false,
    }
    spew.Printf("before src %+v\tdst %+v\n", src, dst)
    copier.CopyWithOption(&dst, src, copier.Option{IgnoreEmpty: true, DeepCopy: true})
    spew.Printf("after  src %+v\tdst %+v\n", src, dst)
    src.M["b"] = 99
    src.S[1] = 1
    dst.S[0] = 2
    spew.Printf("last  src %+v\tdst %+v\n\n", src, dst)
}

輸出:

before src {A:[9 10 0] S:[12 0] E:[] C: V:val M:map[A::1 b:0] AC:{Name:[ ] C:<nil>} s:true}    dst {A:[1 2 3] S:[4 5 6 7] E:[9 10] C:char V:ha M:map[C::3 b:4 .:0] AC:{Name:[Y Z] C:<nil>} s:false}
after  src {A:[9 10 0] S:[12 0] E:[] C: V:val M:map[A::1 b:0] AC:{Name:[ ] C:<nil>} s:true}    dst {A:[9 10 0] S:[12 0 6 7] E:[9 10] C:char V:val M:map[A::1 C::3 b:0 .:0] AC:{Name:[Y Z] C:<nil>} s:true}
last  src {A:[9 10 0] S:[12 1] E:[] C: V:val M:map[A::1 b:99] AC:{Name:[ ] C:<nil>} s:true}    dst {A:[9 10 0] S:[2 0 6 7] E:[9 10] C:char V:val M:map[C::3 b:0 .:0 A::1] AC:{Name:[Y Z] C:<nil>} s:true}

這次的代碼我加上了 IgnoreEmpty: true, 也就是復(fù)制時忽略空的值。 也就說可以當(dāng)作值 merge 用。

然后,又測試了一下變量獨立性。復(fù)制之后,srcdst 兩個變量再無瓜葛,對其中一個值的任意改動都不會同步到另一個值。

但是,這個 merge 的表現(xiàn),可能不是你想的那樣,

src.S = []int32{12, 0}
dst.S = []int32{4, 5, 6, 7}
## 調(diào)用 copy 后, 你預(yù)期的結(jié)果是什么?[6/7]
6. dst.S = []int32{12, 0}
7. dst.S = []int32{12, 0, 6, 7}
  • 選項6: 嗯,原來是 {12, 0} 復(fù)制給 dst 就是 {12, 0}
  • 選項7: 這個是切片,你只給我 0,1 位的值,copier把 0,1 位置的值 copy 了,dst后面2,3位的值,src沒給出,那就不管。所以就是 {12, 0, 6, 7}

這塊的表現(xiàn),我覺得是有爭議的,大佬們在評論區(qū)留下你預(yù)期選項,看看大家是不是都這樣想的。

實際運行結(jié)果,見上面的代碼輸出就能找到答案。

結(jié)語

copier 本來是一個短小精悍的工具庫,也沒想要水一篇,最近使用時,突然踩坑,就特開一篇,和大家分享一下踩坑經(jīng)驗。

在使用外部庫的時候,還是建議去 github 上看看詳細(xì)說明, 或者上 pkg.go.dev 看看它暴露出來出的接口以及說明。更或者進(jìn)行完整的測試,充分了解它之后,再使用。

以上就是Golang Copier入門到入坑探究的詳細(xì)內(nèi)容,更多關(guān)于Golang Copier入門的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go語言Pflag Viper Cobra 核心功能使用介紹

    go語言Pflag Viper Cobra 核心功能使用介紹

    這篇文章主要為大家介紹了go語言Pflag Viper Cobra 核心功能使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • go中的unsafe包及使用詳解

    go中的unsafe包及使用詳解

    Unsafe code是一種繞過go類型安全和內(nèi)存安全檢查的Go代碼。這篇文章主要介紹了go中的unsafe包,需要的朋友可以參考下
    2019-07-07
  • 解決golang時間字符串轉(zhuǎn)time.Time的坑

    解決golang時間字符串轉(zhuǎn)time.Time的坑

    這篇文章主要介紹了解決golang時間字符串轉(zhuǎn)time.Time的坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang實現(xiàn)redis的延時消息隊列功能示例

    golang實現(xiàn)redis的延時消息隊列功能示例

    這篇文章主要介紹了golang實現(xiàn)redis的延時消息隊列功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 深入理解go slice結(jié)構(gòu)

    深入理解go slice結(jié)構(gòu)

    這篇文章主要介紹了go slice結(jié)構(gòu),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-09-09
  • 優(yōu)雅管理Go?Project生命周期

    優(yōu)雅管理Go?Project生命周期

    這篇文章主要為大家介紹了如何優(yōu)雅的管理Go?Project生命周期,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Go緩沖channel和非緩沖channel的區(qū)別說明

    Go緩沖channel和非緩沖channel的區(qū)別說明

    這篇文章主要介紹了Go緩沖channel和非緩沖channel的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言常見哈希函數(shù)的使用

    Go語言常見哈希函數(shù)的使用

    哈希表(Hash table,也叫散列表),是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。也就是說,它通過把關(guān)鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。具體的介紹網(wǎng)上有很詳細(xì)的描述,如閑聊哈希表 ,這里就不再累述了;
    2015-03-03
  • go語言中HTTPRouter的算法演進(jìn)

    go語言中HTTPRouter的算法演進(jìn)

    這篇文章主要從開發(fā)中常見的應(yīng)用場景?“路由管理”?為例,為大家詳細(xì)介紹一下三種常用的實現(xiàn)方案背后的數(shù)據(jù)結(jié)構(gòu)和算法,感興趣的小伙伴可以了解一下
    2023-08-08
  • SingleFlight模式的Go并發(fā)編程學(xué)習(xí)

    SingleFlight模式的Go并發(fā)編程學(xué)習(xí)

    這篇文章主要為大家介紹了SingleFlight模式的Go并發(fā)編程學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04

最新評論

磴口县| 广宁县| 噶尔县| 巫溪县| 栾川县| 长海县| 会宁县| 鹤庆县| 萨嘎县| 盖州市| 汕尾市| 洪洞县| 蓬莱市| 五家渠市| 达孜县| 承德县| 乐安县| 墨脱县| 娄烦县| 定远县| 桂东县| 南江县| 陆良县| 曲麻莱县| 尚志市| 宁化县| 京山县| 兴山县| 庄浪县| 麦盖提县| 阿勒泰市| 左权县| 临猗县| 唐山市| 柏乡县| 玉田县| 环江| 伊宁县| 兴海县| 大姚县| 定边县|