欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go切片和指針切片示例詳解

 更新時(shí)間:2024年04月15日 09:00:35   作者:香吧香  
在Go語(yǔ)言中,切片(Slice)和指針的切片(即切片中每個(gè)元素都是指向某種數(shù)據(jù)類型的指針)是兩個(gè)不同的概念,它們各自具有特定的用途和優(yōu)勢(shì),這篇文章主要介紹了go切片和指針切片,需要的朋友可以參考下

在Go語(yǔ)言中,切片(Slice)和指針的切片(即切片中每個(gè)元素都是指向某種數(shù)據(jù)類型的指針)是兩個(gè)不同的概念,它們各自具有特定的用途和優(yōu)勢(shì)。

切片(Slice)

  切片是對(duì)數(shù)組的一個(gè)連續(xù)片段的引用,它提供了對(duì)數(shù)組元素集合的抽象表示。切片底層數(shù)據(jù)結(jié)構(gòu)都是數(shù)組,它包含三個(gè)關(guān)鍵部分:指向數(shù)組起始元素的指針、切片長(zhǎng)度和切片容量。切片長(zhǎng)度是指切片當(dāng)前包含的元素個(gè)數(shù),而切片容量是指從切片的起始元素到底層數(shù)組的最后一個(gè)元素的個(gè)數(shù)。

  切片的一個(gè)重要特性是它提供了對(duì)底層數(shù)組的動(dòng)態(tài)視圖。這意味著你可以通過(guò)切片來(lái)訪問(wèn)、修改和操作數(shù)組的一部分或全部元素,而無(wú)需復(fù)制整個(gè)數(shù)組。此外,切片還可以方便地進(jìn)行擴(kuò)容和縮容操作,以滿足不同場(chǎng)景下的需求。

  示例

package main  
import "fmt"  
func main() {  
    // 定義一個(gè)數(shù)組  
    array := [5]int{1, 2, 3, 4, 5}  
    // 創(chuàng)建一個(gè)切片,引用數(shù)組的前三個(gè)元素  
    slice := array[:3]  
    // 打印切片元素  
    fmt.Println(slice) // 輸出: [1 2 3]  
    // 修改切片元素,也會(huì)修改底層數(shù)組對(duì)應(yīng)位置的元素  
    slice[1] = 100  
    fmt.Println(array) // 輸出: [1 100 3 4 5]  
}

指針的切片

  指針的切片是一個(gè)切片,但其元素是指針,指向某種數(shù)據(jù)類型的實(shí)例。這意味著每個(gè)元素都是一個(gè)地址,通過(guò)這個(gè)地址可以間接訪問(wèn)和操作實(shí)際的數(shù)據(jù)。指針的切片常用于需要存儲(chǔ)大量數(shù)據(jù)且希望避免數(shù)據(jù)復(fù)制的場(chǎng)景,或者當(dāng)需要在切片中存儲(chǔ)可變大小的對(duì)象時(shí)。

  使用指針的切片可以節(jié)省內(nèi)存空間,因?yàn)橹恍枰鎯?chǔ)指針而不是實(shí)際的數(shù)據(jù)。同時(shí),通過(guò)指針可以方便地修改原始數(shù)據(jù)。然而,這也帶來(lái)了額外的復(fù)雜性和風(fēng)險(xiǎn),因?yàn)樾枰⌒奶幚碇羔樀慕庖煤蛢?nèi)存管理。

  示例

package main  
import "fmt"  
type Person struct {  
    Name string  
    Age  int  
}  
func main() {  
    // 創(chuàng)建幾個(gè)Person實(shí)例的指針  
    person1 := &Person{Name: "Alice", Age: 30}  
    person2 := &Person{Name: "Bob", Age: 25}  
    // 創(chuàng)建一個(gè)指針的切片,存儲(chǔ)這些指針  
    people := []*Person{person1, person2}  
    // 通過(guò)指針修改Person實(shí)例的屬性  
    people[0].Age = 31  
    // 打印修改后的Person實(shí)例  
    fmt.Println(people[0].Name, people[0].Age) // 輸出: Alice 31  
}

結(jié)構(gòu)體切片與結(jié)構(gòu)體指針切片的區(qū)別

  • 內(nèi)存占用:

    • 結(jié)構(gòu)體切片:每個(gè)元素都是結(jié)構(gòu)體的一個(gè)完整副本,因此內(nèi)存占用較大。

    • 結(jié)構(gòu)體指針切片:每個(gè)元素只是一個(gè)指向結(jié)構(gòu)體的指針,內(nèi)存占用較小。但是,這并不意味著整體內(nèi)存占用會(huì)小,因?yàn)檫€需要考慮實(shí)際結(jié)構(gòu)體對(duì)象所占用的內(nèi)存。

  • 修改元素:

    • 結(jié)構(gòu)體切片:修改切片中的一個(gè)元素,將直接修改該元素的值,不會(huì)影響其他切片或原始結(jié)構(gòu)體對(duì)象。

    • 結(jié)構(gòu)體指針切片:修改切片中的一個(gè)指針指向的元素,將影響所有指向該元素的指針。如果多個(gè)切片或變量指向同一個(gè)結(jié)構(gòu)體對(duì)象,修改該對(duì)象的內(nèi)容將影響所有引用。

  • 初始化與賦值:

    • 結(jié)構(gòu)體切片:可以直接初始化并賦值。

    • 結(jié)構(gòu)體指針切片:需要先初始化結(jié)構(gòu)體對(duì)象,然后將對(duì)象的地址賦值給切片。

  • nil與空切片:

    • 對(duì)于結(jié)構(gòu)體指針切片,nil切片和空切片(長(zhǎng)度為0的切片)是不同的。nil切片沒(méi)有分配底層數(shù)組,而空切片分配了底層數(shù)組但長(zhǎng)度為0。

    • 對(duì)于結(jié)構(gòu)體切片,通常不會(huì)討論nil切片,因?yàn)榍衅偸桥c底層數(shù)組相關(guān)聯(lián)。

能否直接遍歷結(jié)構(gòu)體切片并賦值給結(jié)構(gòu)體指針切片

  不能直接遍歷結(jié)構(gòu)體切片并賦值給結(jié)構(gòu)體指針切片。因?yàn)榻Y(jié)構(gòu)體切片中的元素是結(jié)構(gòu)體的值,而結(jié)構(gòu)體指針切片中的元素是指向結(jié)構(gòu)體的指針。需要遍歷結(jié)構(gòu)體切片,并分別為每個(gè)元素創(chuàng)建指針,然后將這些指針添加到結(jié)構(gòu)體指針切片中。

示例說(shuō)明

  假設(shè)我們有一個(gè)Person結(jié)構(gòu)體:

type Person struct {  
    Name string  
    Age  int  
}

  結(jié)構(gòu)體切片的使用

// 創(chuàng)建并初始化一個(gè)Person結(jié)構(gòu)體切片  
peopleSlice := []Person{  
    {"Alice", 30},  
    {"Bob", 25},  
}  
// 修改切片中的一個(gè)元素  
peopleSlice[0].Age = 31  
// 遍歷并打印切片中的元素  
for _, person := range peopleSlice {  
    fmt.Println(person.Name, person.Age)  
}

結(jié)構(gòu)體指針切片的使用

// 創(chuàng)建并初始化一些Person結(jié)構(gòu)體對(duì)象  
alice := Person{"Alice", 30}  
bob := Person{"Bob", 25}  
// 創(chuàng)建一個(gè)Person指針切片,并將結(jié)構(gòu)體對(duì)象的地址添加到切片中  
peoplePtrSlice := []*Person{&alice, &bob}  
// 修改切片中的一個(gè)指針指向的元素  
peoplePtrSlice[0].Age = 31 // 這將改變alice的年齡,因?yàn)閜eoplePtrSlice[0]指向alice  
// 遍歷并打印切片中的元素(通過(guò)解引用指針)  
for _, personPtr := range peoplePtrSlice {  
    fmt.Println(personPtr.Name, personPtr.Age)  
}  
// 如果想要遍歷結(jié)構(gòu)體切片并賦值給結(jié)構(gòu)體指針切片,你需要這樣做:  
peopleSlice := []Person{  
    {"Charlie", 28},  
    {"David", 35},  
}  
// 初始化一個(gè)空的Person指針切片,長(zhǎng)度與peopleSlice相同  
peoplePtrSlice = make([]*Person, len(peopleSlice))  
// 遍歷peopleSlice,為peoplePtrSlice分配新的指針  
for i, person := range peopleSlice {  
    // 創(chuàng)建person的一個(gè)副本,并獲取其地址,然后賦值給peoplePtrSlice  
    peoplePtrSlice[i] = &Person{Name: person.Name, Age: person.Age}  
}  
// 現(xiàn)在peoplePtrSlice包含了指向peopleSlice中元素副本的指針

  在上面的示例中,peoplePtrSlice是通過(guò)遍歷peopleSlice并創(chuàng)建每個(gè)元素的副本的地址來(lái)初始化的。如果你想要peoplePtrSlice中的指針指向peopleSlice中的相同對(duì)象(而不是副本),你需要確保這些對(duì)象是通過(guò)new函數(shù)或通過(guò)&操作符在堆上分配的,并且它們的地址被添加到peoplePtrSlice中。但是,在大多數(shù)情況下,你可能不希望這樣做,因?yàn)檫@會(huì)導(dǎo)致切片之間共享相同的對(duì)象,從而可能引起意外的副作用。

能否直接遍歷結(jié)構(gòu)體指針切片并賦值給結(jié)構(gòu)體切片

  不能直接遍歷結(jié)構(gòu)體指針切片并賦值給結(jié)構(gòu)體切片。結(jié)構(gòu)體指針切片中的元素是指向結(jié)構(gòu)體的指針,而結(jié)構(gòu)體切片中的元素是結(jié)構(gòu)體的值。因此,如果你嘗試直接將指針切片中的指針賦值給結(jié)構(gòu)體切片,你會(huì)得到的是指針的值(即內(nèi)存地址),而不是結(jié)構(gòu)體對(duì)象本身的值。

  要遍歷結(jié)構(gòu)體指針切片并將指針指向的結(jié)構(gòu)體對(duì)象賦值給結(jié)構(gòu)體切片,你需要對(duì)每個(gè)指針進(jìn)行解引用,獲取其指向的結(jié)構(gòu)體對(duì)象,然后將該對(duì)象賦值給結(jié)構(gòu)體切片中的相應(yīng)位置。

  下面是一個(gè)詳細(xì)的示例說(shuō)明和分析:

package main  
import (  
    "fmt"  
)  
// 定義Person結(jié)構(gòu)體  
type Person struct {  
    Name string  
    Age  int  
}  
func main() {  
    // 初始化一些Person結(jié)構(gòu)體對(duì)象,并獲取它們的地址  
    alice := &Person{"Alice", 30}  
    bob := &Person{"Bob", 25}  
    // 創(chuàng)建一個(gè)Person指針切片  
    peoplePtrSlice := []*Person{alice, bob}  
    // 創(chuàng)建一個(gè)與peoplePtrSlice長(zhǎng)度相同的Person結(jié)構(gòu)體切片  
    peopleSlice := make([]Person, len(peoplePtrSlice))  
    // 遍歷peoplePtrSlice,解引用指針并將結(jié)構(gòu)體對(duì)象賦值給peopleSlice  
    for i, personPtr := range peoplePtrSlice {  
        peopleSlice[i] = *personPtr // 解引用指針,獲取結(jié)構(gòu)體對(duì)象  
    }  
    // 現(xiàn)在peopleSlice包含了peoplePtrSlice中指針指向的結(jié)構(gòu)體對(duì)象的副本  
    fmt.Println(peopleSlice) // 輸出: [{Alice 30} {Bob 25}]  
    // 修改peopleSlice中的元素,不會(huì)影響peoplePtrSlice或原始結(jié)構(gòu)體對(duì)象  
    peopleSlice[0].Age = 31  
    fmt.Println(peopleSlice) // 輸出: [{Alice 31} {Bob 25}]  
    fmt.Println(peoplePtrSlice) // 輸出: [&{Alice 30} &{Bob 25}],peoplePtrSlice中的元素未改變  
}

  在這個(gè)示例中:

  • 我們首先創(chuàng)建了兩個(gè)Person結(jié)構(gòu)體對(duì)象的指針alicebob
  • 然后我們創(chuàng)建了一個(gè)包含這兩個(gè)指針的peoplePtrSlice切片。
  • 接著我們創(chuàng)建了一個(gè)與peoplePtrSlice長(zhǎng)度相同的空Person結(jié)構(gòu)體切片peopleSlice。
  • 在遍歷peoplePtrSlice時(shí),我們使用*personPtr來(lái)解引用指針,并將得到的結(jié)構(gòu)體對(duì)象賦值給peopleSlice中的對(duì)應(yīng)位置。
  • 最后,我們驗(yàn)證了修改peopleSlice中的元素不會(huì)影響peoplePtrSlice或原始的結(jié)構(gòu)體對(duì)象。

  需要注意的是,這樣做會(huì)創(chuàng)建結(jié)構(gòu)體對(duì)象的副本。如果你只是想引用原始的對(duì)象而不是它們的副本,你應(yīng)該直接使用指針切片,而不是創(chuàng)建結(jié)構(gòu)體切片。如果你確實(shí)需要結(jié)構(gòu)體切片,并且想保持對(duì)原始對(duì)象的引用,那么你需要重新考慮你的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì),因?yàn)榻Y(jié)構(gòu)體切片本身不保存對(duì)原始對(duì)象的引用。

到此這篇關(guān)于go切片和指針切片的文章就介紹到這了,更多相關(guān)go切片和指針切片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang實(shí)踐之Error創(chuàng)建和處理詳解

    Golang實(shí)踐之Error創(chuàng)建和處理詳解

    在 C#、Java 等語(yǔ)言中常常使用 try...catch的方式來(lái)捕獲異常,但是在Golang 對(duì)于錯(cuò)誤處理有不同的方式,像網(wǎng)上也有很多對(duì) error 處理的最佳實(shí)踐的文章,其中很多其實(shí)就是對(duì) error 的統(tǒng)一封裝,使用規(guī)范進(jìn)行約束,本文主要是記錄自己對(duì)處理 Error 的一些認(rèn)識(shí)和學(xué)習(xí)
    2023-09-09
  • 利用Go語(yǔ)言實(shí)現(xiàn)二叉搜索樹(shù)

    利用Go語(yǔ)言實(shí)現(xiàn)二叉搜索樹(shù)

    二叉樹(shù)是一種常見(jiàn)并且非常重要的數(shù)據(jù)結(jié)構(gòu),在很多項(xiàng)目中都能看到二叉樹(shù)的身影,當(dāng)然它也有很多變種,本文要介紹的是二叉搜索樹(shù)的實(shí)現(xiàn),希望對(duì)大家有所幫助
    2023-07-07
  • Go語(yǔ)言Echo服務(wù)器的方法

    Go語(yǔ)言Echo服務(wù)器的方法

    這篇文章主要介紹了Go語(yǔ)言Echo服務(wù)器的方法,實(shí)例分析了Echo服務(wù)器的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go中的代碼換行問(wèn)題

    Go中的代碼換行問(wèn)題

    這篇文章主要介紹了Go中的代碼換行問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 使用Go實(shí)現(xiàn)偽靜態(tài)URL重寫(xiě)功能

    使用Go實(shí)現(xiàn)偽靜態(tài)URL重寫(xiě)功能

    在Web開(kāi)發(fā)中,偽靜態(tài)URL已成為優(yōu)化網(wǎng)站架構(gòu)和提升SEO的常用技術(shù)手段,偽靜態(tài)URL是一種介于動(dòng)態(tài)URL和靜態(tài)URL之間的解決方案,本文給大家介紹了如何使用Go實(shí)現(xiàn)偽靜態(tài)URL重寫(xiě)功能,需要的朋友可以參考下
    2024-08-08
  • Go語(yǔ)言文件讀寫(xiě)操作案例詳解

    Go語(yǔ)言文件讀寫(xiě)操作案例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言文件讀寫(xiě)操作案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • golang常見(jiàn)接口限流算法的實(shí)現(xiàn)

    golang常見(jiàn)接口限流算法的實(shí)現(xiàn)

    本文主要介紹了golang常見(jiàn)接口限流算法的實(shí)現(xiàn),包含固定窗口、滑動(dòng)窗口、漏桶和令牌桶,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • 一文帶你了解Go語(yǔ)言中time包的時(shí)間常用操作

    一文帶你了解Go語(yǔ)言中time包的時(shí)間常用操作

    在日常開(kāi)發(fā)中,我們避免不了時(shí)間的使用,我們可能需要獲取當(dāng)前時(shí)間,然后格式化保存,也可能需要在時(shí)間類型與字符串類型之間相互轉(zhuǎn)換等。本文將會(huì)對(duì)?Go?time?包里面的常用函數(shù)和方法進(jìn)行介紹,需要的可以參考一下
    2022-12-12
  • golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式

    golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式

    這篇文章主要介紹了golang原生http包實(shí)現(xiàn)各種情況的get請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Go語(yǔ)言獲取本機(jī)邏輯CPU數(shù)量的方法

    Go語(yǔ)言獲取本機(jī)邏輯CPU數(shù)量的方法

    這篇文章主要介紹了Go語(yǔ)言獲取本機(jī)邏輯CPU數(shù)量的方法,實(shí)例分析了runtime庫(kù)的操作技巧,需要的朋友可以參考下
    2015-03-03

最新評(píng)論