最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你感受Go語言空結(jié)構(gòu)體的魔力

 更新時間:2023年05月23日 09:17:07   作者:Go技術(shù)干貨  
在?Go?語言中,有一種特殊的用法可能讓許多人感到困惑,那就是空結(jié)構(gòu)體,本文將對Go空結(jié)構(gòu)體進行詳解,準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧

前言

在 Go 語言中,有一種特殊的用法可能讓許多人感到困惑,那就是空結(jié)構(gòu)體 struct{}。在本文中,我將對 Go 空結(jié)構(gòu)體進行詳解,準(zhǔn)備好了嗎?準(zhǔn)備一杯你最喜歡的飲料或茶,隨著本文一探究竟吧。

什么是空結(jié)構(gòu)體

不包含任何字段的結(jié)構(gòu)體,就是空結(jié)構(gòu)體。它有以下兩種定義方式:

匿名空結(jié)構(gòu)體

var e sruct{}

命名空結(jié)構(gòu)體

type EmptyStruct struct{}
var e EmptyStruct

空結(jié)構(gòu)體的特點

空結(jié)構(gòu)體主要有以下幾個特點:

  • 零內(nèi)存占用
  • 地址相同
  • 無狀態(tài)

零內(nèi)存占用

空結(jié)構(gòu)體不占用任何內(nèi)存空間,這使得空結(jié)構(gòu)體在內(nèi)存優(yōu)化方面非常有用,我們來通過例子看看是否真的是零內(nèi)存占用:

package main

import (
   "fmt"
   "unsafe"
)

func main() {
   var a int
   var b string
   var e struct{}
   fmt.Println(unsafe.Sizeof(a)) // 4
   fmt.Println(unsafe.Sizeof(b)) // 8
   fmt.Println(unsafe.Sizeof(e)) // 0
}

通過打印結(jié)果對比可知,空結(jié)構(gòu)體內(nèi)存占用為 0。

地址相同

無論創(chuàng)建多少個空結(jié)構(gòu)體,它們所指向的地址都相同的。

package main

import (
   "fmt"
)

func main() {
   var e struct{}
   var e2 struct{}
   fmt.Printf("%p\n", &e)  // 0x90b418
   fmt.Printf("%p\n", &e2) // 0x90b418
   fmt.Println(&e == &e2)    // true
}

無狀態(tài)

由于空結(jié)構(gòu)體不包含任何字段,因此它不能有狀態(tài)。這使得空結(jié)構(gòu)體在表示無狀態(tài)的對象或情況時非常有用。

為什么是零內(nèi)存和地址相同

要理解為什么空結(jié)構(gòu)體在內(nèi)存上是零大小(零內(nèi)存)并且多個空結(jié)構(gòu)體的地址是相同的,需要深入研究 Go 的源碼。

/go/src/runtime/malloc.go

// base address for all 0-byte allocations
var zerobase uintptr
func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
    ······
    if size == 0 {
       return unsafe.Pointer(&zerobase)
    }
    ······

根據(jù) malloc.go 源碼的部分內(nèi)容,當(dāng)要分配的對象大小 size 為 0 時,會返回指向 zerobase 的指針。zerobase 是一個用于分配零字節(jié)對象的基準(zhǔn)地址,它不占用任何實際的內(nèi)存空間。

空結(jié)構(gòu)體的使用場景

空結(jié)構(gòu)體主要有以下三種使用場景:

  • 實現(xiàn) Set 集合類型
  • 用于通道信號
  • 作為方法接收器

實現(xiàn) Set 集合類型

在 Go 語言中,雖然沒有內(nèi)置 Set 集合類型,但是我們可以利用 map 類型來實現(xiàn)一個 Set 集合。由于 map 的 key 具有唯一性,我們可以將元素存儲為 key,而 value 沒有實際作用,為了節(jié)省內(nèi)存,我們可以使用空結(jié)構(gòu)體作為 value 的值。

package main
import"fmt"
type Set[K comparable] map[K]struct{}
func (s Set[K]) Add(val K) {
   s[val] = struct{}{}
}
func (s Set[K]) Remove(val K) {
   delete(s, val)
}
func (s Set[K]) Contains(val K) bool {
   _, ok := s[val]
   return ok
}
func main() {
   set := Set[string]{}
   set.Add("陳明勇")
   fmt.Println(set.Contains("陳明勇")) // true
   set.Remove("陳明勇")
   fmt.Println(set.Contains("陳明勇")) // false
}

用于通道信號

空結(jié)構(gòu)體常用于 Goroutine 之間的信號傳遞,尤其是不關(guān)心通道中傳遞的具體數(shù)據(jù),只需要一個觸發(fā)信號時。例如,我們可以使用空結(jié)構(gòu)體通道來通知一個 Goroutine 停止工作:

package main  
import (  
   "fmt"
   "time"
)  
func main() {  
   quit := make(chanstruct{})  
   gofunc() {  
      // 模擬工作  
      fmt.Println("工作中...")  
      time.Sleep(3 * time.Second)  
      // 關(guān)閉退出信號  
      close(quit)
   }()  
   // 阻塞,等待退出信號被關(guān)閉  
   <-quit  
   fmt.Println("已收到退出信號,退出中...")  
}

在這個例子中,創(chuàng)建了一個通道 quit,并在一個單獨的 Goroutine 中模擬執(zhí)行工作。在完成工作后,關(guān)閉了 quit 通道,表示退出信號。主函數(shù)在 <-quit 處阻塞,直到收到退出信號,然后打印一條消息并退出程序。

由于通道使用的類型是空結(jié)構(gòu)體,因此不會帶來額外的內(nèi)存開銷。

在 Go 標(biāo)準(zhǔn)庫中,context 包中的 Context 接口的 Done() 方法返回一個通道信號,用于通知相關(guān)操作的完成狀態(tài)。這個通道信號的返回值就是使用了空結(jié)構(gòu)體。

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chanstruct{}
    Err() error
    Value(key any) any
}

作為方法接收器

有時候我們需要創(chuàng)建一組方法集的實現(xiàn)(一般來說是實現(xiàn)一個接口),但并不需要在這個實現(xiàn)中存儲任何數(shù)據(jù),這種情況下,我們可以使用空結(jié)構(gòu)體來實現(xiàn):

type Person interface {
   SayHello()
   Sleep()
}
type CMY struct{}
func (c CMY) SayHello() {
   fmt.Println("你好,我叫陳明勇。")
}
func (c CMY) Sleep() {
   fmt.Println("陳明勇睡覺中...")
}

這個例子定義了一個接口 Person 和一個結(jié)構(gòu)體 CMY ,并為 CMY 實現(xiàn)了 Person 接口,定義了一組方法(SayHello 和 Sleep)。

由于 CMY 結(jié)構(gòu)體為空結(jié)構(gòu)體,因此不會帶來額外的內(nèi)存開銷。

小結(jié)

在本文中,首先介紹了 Go 語言 空結(jié)構(gòu)體 的概念和定義方式,它有兩種定義方式;

隨后對 空結(jié)構(gòu)體 的特點進行介紹,包括其零內(nèi)存和多個變量地址相同的特性;

接著進一步深入源碼,探究了為什么空結(jié)構(gòu)體在 Go 語言中是零內(nèi)存且多變量地址相同,原因是當(dāng)要分配的對象大小 size 為 0 時,會返回指向 zerobase 的指針;

最后列舉了空結(jié)構(gòu)體的三個使用場景,通過這些代碼示例,展示了空結(jié)構(gòu)體在實際應(yīng)用中的一些常見用途。

到此這篇關(guān)于一文帶你感受Go語言空結(jié)構(gòu)體的魔力的文章就介紹到這了,更多相關(guān)Go語言空結(jié)構(gòu)體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang?gorm模型結(jié)構(gòu)體的定義示例

    golang?gorm模型結(jié)構(gòu)體的定義示例

    這篇文章主要為大家介紹了golang?gorm模型結(jié)構(gòu)體的定義示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • go?smtp實現(xiàn)郵件發(fā)送示例詳解

    go?smtp實現(xiàn)郵件發(fā)送示例詳解

    這篇文章主要為大家介紹了go?smtp實現(xiàn)郵件發(fā)送示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 詳解如何解決golang定時器引發(fā)的id重復(fù)問題

    詳解如何解決golang定時器引發(fā)的id重復(fù)問題

    這篇文章主要為大家詳細(xì)介紹了如何解決golang定時器引發(fā)的id重復(fù)問題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • 在Golang中正確的修改HTTPRequest的Host的操作方法

    在Golang中正確的修改HTTPRequest的Host的操作方法

    我們工作中經(jīng)常需要通過HTTP請求Server的服務(wù),比如腳本批量請求接口跑數(shù)據(jù),由于一些網(wǎng)關(guān)策略,部分Server會要求請求中Header里面附帶Host參數(shù),所以本文給大家介紹了如何在Golang中正確的修改HTTPRequest的Host,需要的朋友可以參考下
    2023-12-12
  • Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    這篇文章主要介紹了Golang中interface{}轉(zhuǎn)為數(shù)組的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 詳解Golang開啟http服務(wù)的三種方式

    詳解Golang開啟http服務(wù)的三種方式

    這篇文章主要介紹了詳解Golang開啟http服務(wù)的三種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Golang的CSP模型簡介(最新推薦)

    Golang的CSP模型簡介(最新推薦)

    Golang采用了CSP(Communicating?Sequential?Processes,通信順序進程)并發(fā)模型,通過goroutine和channel提供了一種更為簡潔和安全的并發(fā)編程方式,本文將詳細(xì)介紹Golang的CSP并發(fā)模型及其使用方法,感興趣的朋友一起看看吧
    2025-01-01
  • Go語言調(diào)用其它程序并獲得程序輸出的方法

    Go語言調(diào)用其它程序并獲得程序輸出的方法

    這篇文章主要介紹了Go語言調(diào)用其它程序并獲得程序輸出的方法,實例分析了Go調(diào)用cmd程序的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • 利用golang實現(xiàn)pdf中自動換行的表格

    利用golang實現(xiàn)pdf中自動換行的表格

    這篇文章主要給大家介紹了如何利用golang實現(xiàn)pdf中自動換行的表格,文中通過代碼示例給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • MacOS下本地golang環(huán)境搭建詳細(xì)教程

    MacOS下本地golang環(huán)境搭建詳細(xì)教程

    這篇文章主要介紹了MacOS下本地golang環(huán)境搭建詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09

最新評論

台北县| 水富县| 台北市| 历史| 嘉善县| 盐津县| 巩义市| 攀枝花市| 孝昌县| 武平县| 海林市| 镇安县| 凤凰县| 岳普湖县| 隆安县| 星子县| 辽阳县| 马公市| 靖远县| 普洱| 齐齐哈尔市| 瑞安市| 清水河县| 周至县| 江永县| 临猗县| 万安县| 精河县| 调兵山市| 靖江市| 蕲春县| 长阳| 宁陵县| 交城县| 积石山| 团风县| 洛扎县| 尼木县| 和静县| 如东县| 蓬莱市|