Slice Append operating Precautions

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

If the append operation of slice and slice is not well understood, the use of slice as a reference type can result in loss of data
Let's start with an example:

Package Mainimport "FMT" type Dbitem struct {Id int16 Cnt int32}func combineitem (itemList []dbitem, Id int16, Cnt i Nt32) {Item: = Dbitem{id:int16 (Id), Cnt:int32 (Cnt)} itemList = Append (itemList, item) FMT. Printf ("Combineitem itemList addr[%p] cap[%d] len[%d] values:%v \ n", ItemList, Cap (itemList), Len (itemList), itemList)}f UNC main () {itemList: = make ([]dbitem, 1, 5) Combineitem (ItemList, Int16 (1), Int32 (2)) fmt.    Printf ("1.cap without expansion itemList addr[%p] cap[%d] len[%d] values:%v \ n", ItemList, Cap (itemList), Len (itemList), itemList) ItemList = Make ([]dbitem, 5, 5) Combineitem (ItemList, Int16 (1), Int32 (2)) fmt. Printf ("2.cap is expanded, new Dbitem appended at slice last itemList addr[%p] cap[%d] len[%d] values:%v \ n", ItemList, Cap (itemList), Len ( itemList), itemList) itemList = make ([]dbitem, 5, 5) Combineitem (Itemlist[:1], int16 (1), Int32 (2)) fmt. Printf ("3.cap is not expanded, new dbitem in Slice Middle itemList addr[%p] cap[%d] len[%d] values:%v \ n", ItemList, Cap (itemList), Len (itemList), ItemList)} 

Operation Result:
Combineitem itemList addr[0xc4200480f0] cap[5] len[2] values: [{0 0} {1 2}]
1.cap no expansion itemList addr[0xc4200480f0] cap[5] len[1] values: [{0 0}]
Combineitem itemList addr[0xc42003e050] cap[10] len[6] values: [{0 0} {0 0} {0 0} {0 0} {0 0} {1 2}]
2.cap is expanded, new Dbitem appended in slice last itemList addr[0xc420048120] cap[5] len[5] values: [{0 0} {0 0} {0 0} {0 0} {0 0}]
Combineitem itemList addr[0xc420048150] cap[5] len[2] values: [{0 0} {1 2}]
3.cap not expanded, new Dbitem appended in slice itemList addr[0xc420048150] cap[5] len[5] values: [{0 0} {1 2} {0 0} {0 0} {0 0}]

When Len (slice_a) +len (slice_b) <=cap (slice_a) in Slice_c=append (Slice_a,slice_b) does not expand, it will be expanded to twice times the cap (slice_a) if slice Len is greater than 1024 and expands by One-fourth caps. The specific implementation of the following source code:

newcap := old.capif newcap+newcap < cap {    newcap = cap} else {    for {        if old.len < 1024 {            newcap += newcap        } else {            newcap += newcap / 4        }        if newcap >= cap {            break        }    }}

As you can see from Example 2, the slice returned by append points to a new address. But even if there is no expansion, slice point to the same address, why slice_c or not equal to slice_a? In fact, slice is not a simple pointer, but a C-struct implementation:

struct    Slice{    // must not move anything    byte*    array;        // actual data    uintgo    len;        // number of elements    uintgo    cap;        // allocated number of elements};

The source code can be seen in $goroot/src/pkg/runtime/runtime.h.
In the case of no expansion, the data changes passed into the slice_a will affect the value of the slice_a outside the function, because their byte* points to the same address.
In the case of expansion, there is no such effect. Regardless of the expansion or not, the value of slice also depends on Len, so even if Slice's byte* points to the same address, the results are different. So when there is append in the function, do not use slice as a reference type parameter!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.