golang中slice怎么用

小编给大家分享一下golang中slice怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

专注于为中小企业提供成都网站设计、做网站、成都外贸网站建设公司服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业化州免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

slice 结构定义

type slice struct {

    array unsafe.Pointer

    len   int

    cap   int

}

创建slice

// maxSliceCap returns the maximum capacity for a slice.

func maxSliceCap(elemsize uintptr) uintptr {

    if elemsize < uintptr(len(maxElems)) {

        return maxElems[elemsize]

    }

    return _MaxMem / elemsize

}

func makeslice(et *_type, len, cap int) slice {

    // NOTE: The len > maxElements check here is not strictly necessary,

    // but it produces a 'len out of range' error instead of a 'cap out of range' error

    // when someone does make([]T, bignumber). 'cap out of range' is true too,

    // but since the cap is only being supplied implicitly, saying len is clearer.

    // See issue 4085.

    // 计算最大可分配长度

    maxElements := maxSliceCap(et.size)

    if len < 0 || uintptr(len) > maxElements {

        panic(errorString("makeslice: len out of range"))

    }

    if cap < len || uintptr(cap) > maxElements {

        panic(errorString("makeslice: cap out of range"))

    }

    // 分配连续区间

    p := mallocgc(et.size*uintptr(cap), et, true)

    return slice{p, len, cap}

}

slice 扩容

// cap 目标容量

func growslice(et *_type, old slice, cap int) slice {

    if et.size == 0 {

        if cap < old.cap {

            panic(errorString("growslice: cap out of range"))

        }

        // append should not create a slice with nil pointer but non-zero len.

        // We assume that append doesn't need to preserve old.array in this case.

        return slice{unsafe.Pointer(&zerobase), old.len, cap}

    }

    newcap := old.cap

    doublecap := newcap + newcap

    if cap > doublecap {

        newcap = cap

    } else {

        // 小于1024,*2扩容

        if old.len < 1024 {

            newcap = doublecap

        } else {

            // 大于1024,*1.25

            for newcap < cap {

                newcap += newcap / 4

            }

        }

    }

    var lenmem, newlenmem, capmem uintptr

    const ptrSize = unsafe.Sizeof((*byte)(nil))

    switch et.size {

    case 1:

        lenmem = uintptr(old.len)

        newlenmem = uintptr(cap)

        capmem = roundupsize(uintptr(newcap))

        newcap = int(capmem)

    case ptrSize:

        lenmem = uintptr(old.len) * ptrSize

        newlenmem = uintptr(cap) * ptrSize

        capmem = roundupsize(uintptr(newcap) * ptrSize)

        newcap = int(capmem / ptrSize)

    default:

        lenmem = uintptr(old.len) * et.size

        newlenmem = uintptr(cap) * et.size

        capmem = roundupsize(uintptr(newcap) * et.size)

        newcap = int(capmem / et.size)

    }

    if cap < old.cap || uintptr(newcap) > maxSliceCap(et.size) {

        panic(errorString("growslice: cap out of range"))

    }

    var p unsafe.Pointer

    if et.kind&kindNoPointers != 0 {

        p = mallocgc(capmem, nil, false)

        memmove(p, old.array, lenmem)

        // The append() that calls growslice is going to overwrite from old.len to cap (which will be the new length).

        // Only clear the part that will not be overwritten.

        memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)

    } else {

        // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.

        p = mallocgc(capmem, et, true)

        if !writeBarrier.enabled {

            memmove(p, old.array, lenmem)

        } else {

            for i := uintptr(0); i < lenmem; i += et.size {

                typedmemmove(et, add(p, i), add(old.array, i))

            }

        }

    }

    // 新slice

    return slice{p, old.len, newcap}

}

以上是“golang中slice怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!

网页名称:golang中slice怎么用
转载源于:https://www.cdcxhl.com/article2/jhcpoc.html

成都网站建设公司_创新互联,为您提供做网站自适应网站企业建站ChatGPTGoogleApp开发

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

外贸网站建设