Go-append use method and matters needing attention

Source: Internet
Author: User
Tags builtin sprintf
Grammar prototypes

In Go/src/builtin/builtin.go, the append is described as follows:

The Append built-in function appends elements to the end of a slice. If
//It has sufficient capacity, the destination are resliced to accommodate the
//new elements. If it does not, a new underlying array would be allocated.
Append returns the updated slice. It is therefore necessary
to store the//result of append, often in the variable holding the slice itself:
//
  
   slice = Append (Slice, elem1, elem2)
//  slice = append (slice, anotherslice ...)
As a special case, it was legal to append a string to a byte slice, like this:
//  slice = append ([]byte ("Hello ")," World "...)
Func Append (Slice []type, Elems ... Type) []type

  
Key pointsAdd one or more elements behind a slice with append; the slice of append has a underlying array, which is the relationship between slice and array, and slice has a concept of length and capability; If Slice has the remaining space to add these new elements, then append will place the new element in the free space behind slice, and if slice's space is not enough to drop the new element, then you need to recreate an array, which may be alloc, It is also possible to assign this new array in a realloc way, which means that the new slice may be at the same starting address as the previous slice, or it may not be a new address. -In general, it's a new address. Once the new address has been assigned, the elements in the original slice are copied to the new slice one by one and returned. analogy

This slice can be likened to C + + vectors. To this end, you can refer to the C + + source code anatomy 4.2.5 vector structure and memory management. Example Code

Package main

Import (
    "FMT"
)

type Employee struct {
    name string City
    string
}

func (E *employee) string () string {
    return FMT. Sprintf ("employee[address:%p, Name:%s, City:%s]", E, E.name, e.city)
}

var g_employees = []employee{}
// var g_employees = make ([]employee, 0, 4)

func Add (Employee *employee) {
    g_employees = append (G_employees, *empl Oyee)
}

func debug () {
    count: = Len (g_employees) for
    I: = 0; i < count; i++ {
        fmt. Printf ("%d:%s\n", I, & (G_employees[i]))
    }
    fmt. Println ()
}

func main () {one
    : = employee{name: "Name1", City: "City1"}:
    = employee{name: "name2 ", City:" City2 "}
    Three: = employee{name: ' Name3 ', City: ' City3 '} four
    : = employee{name: ' Name4 ', City: ' City4 '} Add (&one) debug () Add (&two) debug ()
    Add (

    &three)
    debug ()

    Add ( &four)
    debug ()
}
Run Results
Case 1:var g_employees = []employee{} 0:employee[address:0xc42000e100, Name:name1, City:city1] 0:employee[address: 0XC4200101C0, Name:name1, City:city1] 1:employee[address:0xc4200101e0, name:name2, City:city2] 0:employee[address : 0xc420086000, Name:name1, City:city1] 1:employee[address:0xc420086020, name:name2, City:city2] 2:employee[address : 0xc420086040, Name:name3, City:city3] 0:employee[address:0xc420086000, name:name1, City:city1] 1:employee[addres s:0xc420086020, Name:name2, City:city2] 2:employee[address:0xc420086040, Name:name3, City:city3] 3:employee[addres s:0xc420086060, Name:name4, City:city4] case 2:var g_employees = make ([]employee, 0, 4) 0:employee[address:0xc4200 74000, Name:name1, City:city1] 0:employee[address:0xc420074000, name:name1, City:city1] 1:employee[address:0xc420 074020, Name:name2, City:city2] 0:employee[address:0xc420074000, name:name1, City:city1] 1:employee[address:0xc42 0074020, Name:name2, CITy:city2] 2:employee[address:0xc420074040, Name:name3, City:city3] 0:employee[address:0xc420074000, name:name1, C Ity:city1] 1:employee[address:0xc420074020, name:name2, City:city2] 2:employee[address:0xc420074040, Name:name3, C
 Ity:city3] 3:employee[address:0xc420074060, Name:name4, City:city4]
Analysis

In debug printing, the address of the object is specially printed and processed. Through the output, you can have the following conclusion: When an capability is 0, add an element on the empty slice, add 1, 2, 3 will reallocate storage space, accompanied by the object copy. changing objects with constant pointers

If the object is stored in the slice, you should pay special attention when handling these objects with pointers. For example, now the global variable takes the first way:

var g_employees = []employee{}

The main () code should read:

Func Main () {one
    : = employee{name: "Name1", City: "City1"}--:
    = employee{name: "Name2", City: "City2"}
    Three: = employee{name: ' Name3 ', City: ' City3 '} four
    : = employee{name: ' Name4 ', City: ' City4 '}

    Add (&one)
    debug ()

    var p *employee
    p = & (G_employees[0])
    FMT. Printf ("P:%s\n\n", p)

    Add (&two)
    debug ()
    FMT. Printf ("P:%s\n\n", p)

    Add (&three)
    debug ()
    FMT. Printf ("P:%s\n\n", p)

    Add (&four)
    debug ()
    FMT. Printf ("P:%s\n\n", p)
}

Once an element has been added, a pointer is defined to point to the element. Operation Result:

0:employee[address:0xc420074000, Name:name1, City:city1]

p:employee[address:0xc420074000, name:name1, city:cit Y1]

0:employee[address:0xc420076140, name:name1, City:city1]
1:employee[address:0xc420076160, name:name2, City:city2]

p:employee[address:0xc420074000, name:name1, City:city1]

0:employee[address:0xc420082000, Name:name1, City:city1]
1:employee[address:0xc420082020, name:name2, City:city2]
2:employee[address:0xc42 0082040, Name:name3, City:city3]

p:employee[address:0xc420074000, name:name1, city:city1]

0:employee[addre ss:0xc420082000, Name:name1, City:city1]
1:employee[address:0xc420082020, name:name2, City:city2]
2:emplo yee[address:0xc420082040, Name:name3, City:city3]
3:employee[address:0xc420082060, Name:name4, City:city4]
  p:employee[address:0xc420074000, Name:name1, City:city1]

You can see that the address pointed to by the pointer remains the same, but it is not the object we expected. work

The

Now stores the object address in slice, not the object. Example One

Package main import ("FMT") type Employee struct {name string City string} func (e *employee) string () s Tring {return FMT. Sprintf ("employee[address:%p, Name:%s, City:%s]", E, E.name, e.city)} var g_employees = []*employee{} func Add (Emplo  Yee *employee) {g_employees = append (G_employees, Employee)} func debug () {count: = Len (g_employees) for I : = 0; I < count; i++ {fmt. Printf ("%d:%s\n", I, G_employees[i])} FMT. Println ()} func main () {one: = Employee{name: "Name1", City: "City1"}, and "Employee{name": "Name2", City: "City2 
    '} Three: = Employee{name: ' Name3 ', City: ' City3 '} Four: = Employee{name: ' Name4 ', City: ' City4 '} Add (&one) Debug () var p *employee p = g_employees[0] FMT. Printf ("P:%s\n\n", p) Add (&two) debug () Fmt. Printf ("P:%s\n\n", p) Add (&three) debug () Fmt. Printf ("P:%s\n\n", p) Add (&four) debug () Fmt. Printf ("P:%s\n\n", p)
}
 

Operation Result:

0:EMPLOYEE[ADDRESS:0XC42000E1A0, Name:name1, City:city1]

p:employee[address:0xc42000e1a0, name:name1, city:cit Y1]

0:employee[address:0xc42000e1a0, name:name1, City:city1]
1:employee[address:0xc42000e1c0, name:name2, City:city2]

p:employee[address:0xc42000e1a0, name:name1, City:city1]

0:employee[address:0xc42000e1a0, Name:name1, City:city1]
1:employee[address:0xc42000e1c0, name:name2, City:city2]
2:employee[address:0xc42 000E1E0, Name:name3, City:city3]

p:employee[address:0xc42000e1a0, name:name1, city:city1]

0:employee[addre SS:0XC42000E1A0, Name:name1, City:city1]
1:employee[address:0xc42000e1c0, name:name2, City:city2]
2:emplo YEE[ADDRESS:0XC42000E1E0, Name:name3, City:city3]
3:employee[address:0xc42000e200, Name:name4, City:city4]
  P:EMPLOYEE[ADDRESS:0XC42000E1A0, Name:name1, City:city1]
Example Two
Package main

Import (
    "FMT"
)

type Employee struct {
    name string City
    string
}

func (E *employee) string () string {
    return FMT. Sprintf ("employee[address:%p, Name:%s, City:%s]", E, E.name, e.city)
}

var g_employees = []*employee{}

F UNC Add (index int) {
    g_employees = append (g_employees,
        &employee{
            fmt. Sprintf ("name%d", index),
            FMT. Sprintf ("city%d", Index)})
}

func debug () {
    count: = Len (g_employees) for
    I: = 0; i < count; i++ { C20/>fmt. Printf ("%d:%s\n", I, G_employees[i])
    }
    fmt. Println ()
}

func main () {
    Add (1)
    debug ()

    var p *employee
    p = g_employees[0]
    fmt. Printf ("P:%s\n\n", p)

    Add (2)
    debug ()
    FMT. Printf ("P:%s\n\n", p)

    Add (3)
    debug ()
    FMT. Printf ("P:%s\n\n", p)

    Add (4)
    debug ()
    FMT. Printf ("P:%s\n\n", p)
}

The result of the operation is unchanged.

Related Article

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.