国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Table of Contents
Get sub -slicing
Home Backend Development Golang Go Slices and Subslices: Understanding Shared Memory and Avoiding `append()` Pitfalls

Go Slices and Subslices: Understanding Shared Memory and Avoiding `append()` Pitfalls

Jan 29, 2025 am 12:21 AM

Go Slices and Subslices: Understanding Shared Memory and Avoiding `append()` Pitfalls

In -depth understanding of GO language slicing: shared memory and

trap append() Hi everyone! Welcome to my blog. ? If you are here, you may have just come into contact with Golang, or you are an experienced developer, and you want to understand the internal working principle of the section. So let's start!

GO language is highly praised because of its simplicity and efficiency -as people often say, "the GO language is to complete the work." For developers from C, C or Java and other languages, the simple grammar and ease of use of Go language are refreshing. However, even in the Go language, some characteristics may confuse developers, especially when processing slices and sub -slices. Let's unveil these subtleties and better understand how to avoid common traps of

and sliced ??to share memory.

append() What is the slice in the GO language?

Usually, when you need a data structure to store a series of values, slicing is the first choice in Go language. Their flexibility comes from such a fact: their length is not part of its type. This feature overcomes the restrictions of the array, enabling us to create a single function that can handle any slices and enables the slice to increase or expand according to needs. Although the slice has some similarities with the array, such as both indexing and length, they have different data management methods. Slice acts as a reference to the underlying array, which actually stores the data of slices. In essence, the slice provides a view of some or all elements of the array. Therefore, when you create a slice, Go will automatically process the bottom array of creating sliced ??elements/data.

The shared memory of sliced ??

The array is a continuous memory block, but what makes the slice interesting is how they quote this memory. Let's break down the structure of the slice:

When you create a slice, it contains three components:

Poems pointing to the underlying array
type slice struct {
    array unsafe.Pointer // 指向底層數(shù)組的指針
    len   int           // 切片中的元素數(shù)量
    cap   int           // 底層數(shù)組的容量
}

<切> The length of the slicing (the number of elements it contains)

    <量> Capacity (the number of elements it can contain before the need to increase)
  1. This is where things become interesting. If you have multiple slices that are derived from the same array, changes made by a slice will be reflected in other slices because they share the same underlying array. len
  2. Let's see the following example:
  3. cap
  4. <解> Understand slicing capacity

Before we further deepen, let's try to understand the slicing capacity

. When you get sub -slices from the existing Go language slicing, the

capacity
package main

import "fmt"

func main() {
    // 創(chuàng)建一個具有初始值的切片
    original := []int{1, 2, 3, 4, 5}

    // 創(chuàng)建一個子切片——兩個切片共享相同的底層數(shù)組!
    subslice := original[1:3]

    fmt.Println("未修改的子切片:", subslice)  // 輸出 => 未修改的子切片: [2 3]

    // 修改子切片
    subslice[0] = 42

    fmt.Println("原始切片:", original) // 輸出 => 原始切片: [1 42 3 4 5]
    fmt.Println("修改后的子切片:", subslice)  // 輸出 => 修改后的子切片: [42 3]
}
of the new sub -slicing is determined by the remaining capacity of the original slice from the sub -section. Let's break down a little:

When you create slices from arrays, the length of the slice is the number of elements it originally contained, and its capacity is the total number of elements that it can contain before it needs to grow.

Get sub -slicing

When you get the sub -slicing from the existing slices:

  • The length is the number of elements you specified.
  • <量> Capacity Calculated the capacity of the original slice minus the starting index of sub -slices.
Let's see a detailed example:

type slice struct {
    array unsafe.Pointer // 指向底層數(shù)組的指針
    len   int           // 切片中的元素數(shù)量
    cap   int           // 底層數(shù)組的容量
}
    The original slice has 5 elements, and the length and capacity are 5.
  • When you use <時>, it points to the elements from index 1 to 3 (2, 3, 4).
  • subslice := original[1:4] <<> The
  • length
  • is 4-1 = 3. subslice <<> The capacity
  • is 5-1 = 4, because it starts from index 1 and includes elements to the end of the original slice.
  • subslice <<> Trap!
  • <<>
This is where developers are often trapped. The <函> function in Go language may cause unexpected behaviors when processing sub -sections.

Unused capacity sharing append() The

capacity

of the sub -slicing includes elements that do not belong to their length but located in the original slicing capacity range. This means that if sub -slices increase, it can access or modify these elements. append()

Let's consider this example:

<初> Initially pointing to 2, 3, the capacity is 4 (it can grow to the end of the original slice).

When you add 60, 70 to <追>, it uses the surplus capacity of the original slice.

<<> and
package main

import "fmt"

func main() {
    // 創(chuàng)建一個具有初始值的切片
    original := []int{1, 2, 3, 4, 5}

    // 創(chuàng)建一個子切片——兩個切片共享相同的底層數(shù)組!
    subslice := original[1:3]

    fmt.Println("未修改的子切片:", subslice)  // 輸出 => 未修改的子切片: [2 3]

    // 修改子切片
    subslice[0] = 42

    fmt.Println("原始切片:", original) // 輸出 => 原始切片: [1 42 3 4 5]
    fmt.Println("修改后的子切片:", subslice)  // 輸出 => 修改后的子切片: [42 3]
}
both reflect these changes because they share the same underlying array.
  • subslice Are you surprised?
  • The operation modified the original slice because there is enough capacity in the underlying array. However, if we exceed the scope of capacity or additional elements exceeding the capacity permit, Go will allocate a new array for sub -sections to break the sharing with the original slicing:
  • subslice
  • In this case,
  • created a new underlying array because the original capacity has exceeded. original subslice <免> The best practice of avoiding traps

append() <確> Clarify the capacity

func main() {
    // 原始切片
    original := []int{1, 2, 3, 4, 5}

    // 創(chuàng)建一個子切片
    subslice := original[1:4] // 指向元素 2, 3, 4

    fmt.Println("子切片:", subslice)    // 輸出 => 子切片: [2 3 4]
    fmt.Println("子切片的長度:", len(subslice)) // 輸出 => 子切片的長度: 3
    fmt.Println("子切片的容量:", cap(subslice)) // 輸出 => 子切片的容量: 4
}

append()

The main advantage is:

i. <建> Create a new slice with its own independent underlying array. This is important -it is not just a new section head, but a brand new array in the memory.

II. <然后> Then only transmit the value instead of memory reference. This is like a copy of a file instead of sharing the original file.
  • <完> Use the complete slice expression
func main() {
    original := []int{1, 2, 3, 4, 5}
    subslice := original[1:3] // 指向元素 2, 3

    fmt.Println("追加前原始切片:", original) // 輸出 => [1 2 3 4 5]
    fmt.Println("追加前子切片:", subslice)       // 輸出 => [2 3]
    fmt.Println("子切片的容量:", cap(subslice))    // 輸出 => 4

    // 在容量范圍內追加到子切片
    subslice = append(subslice, 60, 70)

    // 追加到子切片后打印
    fmt.Println("追加后原始切片:", original)  // 輸出 => [1 2 3 60 70]
    fmt.Println("追加后子切片:", subslice)        // 輸出 => [2 3 60 70]
}

<將> When passing the slice to a function that should not modify the original data, consider non -variability

make([]int, len(subslice))

copy() The main advantage is:

    i. Data protection: The original data remains unchanged, prevent accidents and side effects
  • II. Predicate behavior: The effect of the function on the input does not hide

    III. Parallel security: During the processing process, the original data can be used safely in other goroutine

    <住> Remember:

      Slice is a reference to the underlying array
    • Sub -slicing and parental sharing memory
    • <創(chuàng)> Whether the creation of a new underlying array depends on the capacity
    • append() When adding elements of sub -slicing elements with capacity, it will modify the data of the parent slicing.
    • When you want to avoid sharing, please use explicit memory management
    • When processing sub -slices, please perform any of the following operations:
    I wish you a happy code. Remember, the greater the ability, the greater the responsibility, especially in the sharing of memory! ?
    type slice struct {
        array unsafe.Pointer // 指向底層數(shù)組的指針
        len   int           // 切片中的元素數(shù)量
        cap   int           // 底層數(shù)組的容量
    }

    Congratulations on reading this article.

    Do you think this resource is helpful? Do you have any questions? Or did you find an error or typo? Please leave your feedback in the comments. Don't forget to share this resource with others who may benefit from it. Follow me to get more information.

    The above is the detailed content of Go Slices and Subslices: Understanding Shared Memory and Avoiding `append()` Pitfalls. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What are the implications of Go's static linking by default? What are the implications of Go's static linking by default? Jun 19, 2025 am 01:08 AM

Go compiles the program into a standalone binary by default, the main reason is static linking. 1. Simpler deployment: no additional installation of dependency libraries, can be run directly across Linux distributions; 2. Larger binary size: Including all dependencies causes file size to increase, but can be optimized through building flags or compression tools; 3. Higher predictability and security: avoid risks brought about by changes in external library versions and enhance stability; 4. Limited operation flexibility: cannot hot update of shared libraries, and recompile and deployment are required to fix dependency vulnerabilities. These features make Go suitable for CLI tools, microservices and other scenarios, but trade-offs are needed in environments where storage is restricted or relies on centralized management.

How does Go ensure memory safety without manual memory management like in C? How does Go ensure memory safety without manual memory management like in C? Jun 19, 2025 am 01:11 AM

Goensuresmemorysafetywithoutmanualmanagementthroughautomaticgarbagecollection,nopointerarithmetic,safeconcurrency,andruntimechecks.First,Go’sgarbagecollectorautomaticallyreclaimsunusedmemory,preventingleaksanddanglingpointers.Second,itdisallowspointe

How do I create a buffered channel in Go? (e.g., make(chan int, 10)) How do I create a buffered channel in Go? (e.g., make(chan int, 10)) Jun 20, 2025 am 01:07 AM

To create a buffer channel in Go, just specify the capacity parameters in the make function. The buffer channel allows the sending operation to temporarily store data when there is no receiver, as long as the specified capacity is not exceeded. For example, ch:=make(chanint,10) creates a buffer channel that can store up to 10 integer values; unlike unbuffered channels, data will not be blocked immediately when sending, but the data will be temporarily stored in the buffer until it is taken away by the receiver; when using it, please note: 1. The capacity setting should be reasonable to avoid memory waste or frequent blocking; 2. The buffer needs to prevent memory problems from being accumulated indefinitely in the buffer; 3. The signal can be passed by the chanstruct{} type to save resources; common scenarios include controlling the number of concurrency, producer-consumer models and differentiation

How can you use Go for system programming tasks? How can you use Go for system programming tasks? Jun 19, 2025 am 01:10 AM

Go is ideal for system programming because it combines the performance of compiled languages ??such as C with the ease of use and security of modern languages. 1. In terms of file and directory operations, Go's os package supports creation, deletion, renaming and checking whether files and directories exist. Use os.ReadFile to read the entire file in one line of code, which is suitable for writing backup scripts or log processing tools; 2. In terms of process management, the exec.Command function of the os/exec package can execute external commands, capture output, set environment variables, redirect input and output flows, and control process life cycles, which are suitable for automation tools and deployment scripts; 3. In terms of network and concurrency, the net package supports TCP/UDP programming, DNS query and original sets.

How do I call a method on a struct instance in Go? How do I call a method on a struct instance in Go? Jun 24, 2025 pm 03:17 PM

In Go language, calling a structure method requires first defining the structure and the method that binds the receiver, and accessing it using a point number. After defining the structure Rectangle, the method can be declared through the value receiver or the pointer receiver; 1. Use the value receiver such as func(rRectangle)Area()int and directly call it through rect.Area(); 2. If you need to modify the structure, use the pointer receiver such as func(r*Rectangle)SetWidth(...), and Go will automatically handle the conversion of pointers and values; 3. When embedding the structure, the method of embedded structure will be improved, and it can be called directly through the outer structure; 4. Go does not need to force use getter/setter,

What are interfaces in Go, and how do I define them? What are interfaces in Go, and how do I define them? Jun 22, 2025 pm 03:41 PM

In Go, an interface is a type that defines behavior without specifying implementation. An interface consists of method signatures, and any type that implements these methods automatically satisfy the interface. For example, if you define a Speaker interface that contains the Speak() method, all types that implement the method can be considered Speaker. Interfaces are suitable for writing common functions, abstract implementation details, and using mock objects in testing. Defining an interface uses the interface keyword and lists method signatures, without explicitly declaring the type to implement the interface. Common use cases include logs, formatting, abstractions of different databases or services, and notification systems. For example, both Dog and Robot types can implement Speak methods and pass them to the same Anno

How do I use string functions from the strings package in Go? (e.g., len(), strings.Contains(), strings.Index(), strings.ReplaceAll()) How do I use string functions from the strings package in Go? (e.g., len(), strings.Contains(), strings.Index(), strings.ReplaceAll()) Jun 20, 2025 am 01:06 AM

In Go language, string operations are mainly implemented through strings package and built-in functions. 1.strings.Contains() is used to determine whether a string contains a substring and returns a Boolean value; 2.strings.Index() can find the location where the substring appears for the first time, and if it does not exist, it returns -1; 3.strings.ReplaceAll() can replace all matching substrings, and can also control the number of replacements through strings.Replace(); 4.len() function is used to obtain the length of the bytes of the string, but when processing Unicode, you need to pay attention to the difference between characters and bytes. These functions are often used in scenarios such as data filtering, text parsing, and string processing.

How do I use the io package to work with input and output streams in Go? How do I use the io package to work with input and output streams in Go? Jun 20, 2025 am 11:25 AM

TheGoiopackageprovidesinterfaceslikeReaderandWritertohandleI/Ooperationsuniformlyacrosssources.1.io.Reader'sReadmethodenablesreadingfromvarioussourcessuchasfilesorHTTPresponses.2.io.Writer'sWritemethodfacilitateswritingtodestinationslikestandardoutpu

See all articles