为了账号安全,请及时绑定邮箱和手机立即绑定

复制切片的通用方法

复制切片的通用方法

Go
吃鸡游戏 2021-08-23 16:43:19
我需要复制切片(和底层数组的一部分),因此调用者不会改变数组的原始元素。我想我可以编写一个函数来为特定类型的数组执行此操作:func duplicateSliceOfSomeType(sliceOfSomeType []SomeType) []SomeType {    dulicate := make([]SomeType, len(sliceOfSomeType))    copy(duplicate, sliceOfSomeType)    return duplicate}但是有没有办法通用地创建相同的方法,也许没有泛型?func duplicateSlice(slice []?) []?{    duplicate := make([]?, len(slice))    copy(duplicate, slice)    return duplicate}
查看完整描述

3 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

你可以写一个简单的语句来制作一个切片的浅拷贝,


b := append([]T(nil), a...)

这相当于,


b := make([]T, len(a))

copy(b, a)

例如,


package main


import "fmt"


type T int


func main() {

    a := []T{4, 2}


    b := append([]T(nil), a...)


    fmt.Println(&a[0], a, &b[0], b)

    b[0] = 9

    fmt.Println(&a[0], a, &b[0], b)

}

输出:


0x10328000 [4 2] 0x10328020 [4 2]

0x10328000 [4 2] 0x10328020 [9 2]

附录:


反思的常见困难


如果人们是 Go 的新手,他们根本不应该使用反射。


-抢


即使对于专家来说,反思也是微妙的。它揭示了细节,其理解取决于了解语言如何工作的基本知识,在较小程度上,它是如何实现的。即使对于有经验的 Go 程序员来说,这也会令人困惑。对于初出茅庐的 Gopher 来说,首先要学习更重要、更简单的东西。那些过早学习反思的人混淆了他们对这些基础知识的理解。最好保持一臂之力,直到图片的其余部分清晰为止。


-抢


那说,


package main


import (

    "fmt"

    "reflect"

)


func CopySlice(s interface{}) interface{} {

    t, v := reflect.TypeOf(s), reflect.ValueOf(s)

    c := reflect.MakeSlice(t, v.Len(), v.Len())

    reflect.Copy(c, v)

    return c.Interface()

}


type T int


func main() {


    {

        // append

        a := []T{4, 2}

        b := append([]T(nil), a...)

        fmt.Println(&a[0], a, &b[0], b)

        b[0] = 9

        fmt.Println(&a[0], a, &b[0], b)

    }


    {

        // make and copy

        a := []T{4, 2}

        b := make([]T, len(a))

        copy(b, a)

        fmt.Println(&a[0], a, &b[0], b)

        b[0] = 9

        fmt.Println(&a[0], a, &b[0], b)

    }


    {

        // reflection

        a := []T{4, 2}

        b := CopySlice(a).([]T)

        fmt.Println(&a[0], a, &b[0], b)

        b[0] = 9

        fmt.Println(&a[0], a, &b[0], b)

    }


}

输出:


0xc20800a200 [4 2] 0xc20800a210 [4 2]

0xc20800a200 [4 2] 0xc20800a210 [9 2]

0xc20800a290 [4 2] 0xc20800a2a0 [4 2]

0xc20800a290 [4 2] 0xc20800a2a0 [9 2]

0xc20800a310 [4 2] 0xc20800a320 [4 2]

0xc20800a310 [4 2] 0xc20800a320 [9 2]


查看完整回答
反对 回复 2021-08-23
  • 3 回答
  • 0 关注
  • 188 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信