<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      包含引用類(lèi)型字段的自定義結(jié)構(gòu)體,能作為map的key嗎

      1. 引言

      在 Go 語(yǔ)言中,map是一種內(nèi)置的數(shù)據(jù)類(lèi)型,它提供了一種高效的方式來(lái)存儲(chǔ)和檢索數(shù)據(jù)。map是一種無(wú)序的鍵值對(duì)集合,其中每個(gè)鍵與一個(gè)值相關(guān)聯(lián)。使用 map 數(shù)據(jù)結(jié)構(gòu)可以快速地根據(jù)鍵找到對(duì)應(yīng)的值,而無(wú)需遍歷整個(gè)集合。

      在 Go 語(yǔ)言中,map 是一種內(nèi)置的數(shù)據(jù)類(lèi)型,可以通過(guò)以下方式聲明和初始化:

      m := make(map[keyType]valueType)
      

      在使用map時(shí),我們通常會(huì)使用基本數(shù)據(jù)類(lèi)型作為鍵。然而,當(dāng)我們需要將自定義的結(jié)構(gòu)體作為鍵時(shí),就需要考慮結(jié)構(gòu)體中是否包含引用類(lèi)型的字段。引用類(lèi)型是指存儲(chǔ)了數(shù)據(jù)的地址的類(lèi)型,如指針、切片、字典和通道等。在Go中,引用類(lèi)型具有動(dòng)態(tài)的特性,可能會(huì)被修改或指向新的數(shù)據(jù)。這就引發(fā)了一個(gè)問(wèn)題:能否將包含引用類(lèi)型的自定義結(jié)構(gòu)體作為map的鍵呢?

      2. map的基本模型

      了解能否將包含引用類(lèi)型的自定義結(jié)構(gòu)體作為map的鍵這個(gè)問(wèn)題,我們需要先了解下map的基本模型。在Go語(yǔ)言中,map是使用哈希表、實(shí)現(xiàn)的。哈希表是一種以鍵-值對(duì)形式存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),它通過(guò)使用哈希函數(shù)將鍵映射到哈希值。

      哈希函數(shù)是用于將鍵映射到哈希值的算法。它接受鍵作為輸入并生成一個(gè)固定長(zhǎng)度的哈希值。Go語(yǔ)言的 map 使用了內(nèi)部的哈希函數(shù)來(lái)計(jì)算鍵的哈希值。

      而不同的key通過(guò)哈希函數(shù)生成的哈希值可能是相同的,此時(shí)便發(fā)生了哈希沖突。哈希沖突指的是不同的鍵經(jīng)過(guò)哈希函數(shù)計(jì)算后得到相同的哈希值。由于哈希函數(shù)的輸出空間遠(yuǎn)遠(yuǎn)小于鍵的輸入空間,哈希沖突是不可避免的。此時(shí)無(wú)法判斷該key是當(dāng)前哈希表中原本便已經(jīng)存在的元素還是由于哈希沖突導(dǎo)致不同的鍵映射到同一個(gè)bucket。 此時(shí)便需要判斷這兩個(gè)key是否相等。

      因此,在map中,作為map中的key,需要保證其支持對(duì)比操作的,能夠比較兩個(gè)key是否相等。

      3. map 鍵的要求

      從上面map基本的模型介紹中,我們了解到,map中的Key需要支持哈希函數(shù)的計(jì)算,同時(shí)鍵的類(lèi)型必須支持對(duì)比操作。

      map中,計(jì)算key的哈希值,是由默認(rèn)哈希函數(shù)實(shí)現(xiàn)的,對(duì)于map中的key并沒(méi)有額外的要求。

      map中,判斷兩個(gè)鍵是否相等是通過(guò)調(diào)用鍵類(lèi)型的相等運(yùn)算符(==!=)來(lái)完成的,因此key必須確保該類(lèi)型支持 == 操作。這個(gè)要求是由 map 的實(shí)現(xiàn)機(jī)制決定的。map 內(nèi)部使用鍵的相等性來(lái)確定鍵的存儲(chǔ)位置和檢索值。如果鍵的類(lèi)型不可比較,就無(wú)法進(jìn)行相等性比較,從而導(dǎo)致無(wú)法準(zhǔn)確地定位鍵和檢索值。

      在 Go 中,基本數(shù)據(jù)類(lèi)型(如整數(shù)、浮點(diǎn)數(shù)、字符串)和一些內(nèi)置類(lèi)型都是可比較的,因此它們可以直接用作 map 的鍵。然而,自定義的結(jié)構(gòu)體作為鍵時(shí),需要確保結(jié)構(gòu)體的所有字段都是可比較的類(lèi)型。如果結(jié)構(gòu)體包含引用類(lèi)型的字段,那么該結(jié)構(gòu)體就不能直接用作 map 的鍵,因?yàn)橐妙?lèi)型不具備簡(jiǎn)單的相等性比較。

      因此,假如map中的鍵為自定義類(lèi)型,同時(shí)包含引用字段,此時(shí)將無(wú)法作為map的鍵,會(huì)直接編譯失敗,代碼示例如下:

      type Person struct {
         Name    string
         Age     int
         address []Address
      }
      func main() {
          // 這里會(huì)直接編譯不通過(guò)
          m := make(map[Person]int)
      }
      

      其次還有一個(gè)例外,那便是自定義結(jié)構(gòu)體中包含指針類(lèi)型的字段,此時(shí)其是支持==操作的,但是其是使用指針地址來(lái)進(jìn)行hash計(jì)算以及相等性比較的,有可能我們理解是同一個(gè)key,事實(shí)上從map來(lái)看并不是,此時(shí)非常容易導(dǎo)致錯(cuò)誤,示例如下:

      type Person struct {
         Name    string
         Age     int
         address *Address
      }
      func main(){
          m := make(map[Person]int)
          p1 := Person{Name: "Alice", Age: 30, address: &Address{city: "beijing"}}
          p2 := Person{Name: "Alice", Age: 30, address: &Address{city: "beijing"}}
          m[p1] = 1
          m[p2] = 2
          // 輸出1
          fmt.Println(m[p1])
          // 輸出2
          fmt.Println(m[p2])
      }
      

      這里我們定義了一個(gè)Person結(jié)構(gòu)體,包含一個(gè)指針類(lèi)型的字段address。創(chuàng)建了兩個(gè)對(duì)象p1p2,在我們的理解中,其是同一個(gè)對(duì)象,事實(shí)上在map中為兩個(gè)兩個(gè)互不相關(guān)的對(duì)象,主要原因都是使用地址來(lái)進(jìn)行hash計(jì)算以及相等性比較的。

      綜上所述,如果自定義結(jié)構(gòu)體中包含引用類(lèi)型的字段(指針為特殊的引用類(lèi)型),此時(shí)將不能作為map類(lèi)型的key

      4. 為什么不抽取hashCode和equals方法接口,由用戶(hù)自行實(shí)現(xiàn)呢?

      當(dāng)前gomap中哈希值的計(jì)算,其提供了默認(rèn)的哈希函數(shù),不需要由用戶(hù)去實(shí)現(xiàn);其次key的相等性比較,是通過(guò)== 操作符來(lái)實(shí)現(xiàn)的,也不由用戶(hù)自定義比較函數(shù)。那我們就有一個(gè)疑問(wèn)了,為什么不抽取hashCode和equals方法接口,由用戶(hù)來(lái)實(shí)現(xiàn)呢?

      4.1 簡(jiǎn)單性和性能角度

      相等性比較在 Go 語(yǔ)言中使用 == 操作符來(lái)實(shí)現(xiàn),而哈希函數(shù)是由運(yùn)行時(shí)庫(kù)提供的默認(rèn)實(shí)現(xiàn)。這種設(shè)計(jì)選擇我理解可能基于以下幾個(gè)原因:

      1. 簡(jiǎn)單性:對(duì)于默認(rèn)哈希函數(shù)函數(shù)來(lái)說(shuō),其內(nèi)置在語(yǔ)言中的,無(wú)需用戶(hù)額外的實(shí)現(xiàn)和配置。這簡(jiǎn)化了 map 的使用。對(duì)于相等性比較操作,== 操作符進(jìn)行比較是一種直觀且簡(jiǎn)單的方式。在語(yǔ)法上,== 操作符用于比較兩個(gè)值是否相等,這種語(yǔ)法的簡(jiǎn)潔性使得代碼更易讀和理解。
      2. 性能:默認(rèn)的哈希函數(shù)是經(jīng)過(guò)優(yōu)化和測(cè)試的,能夠在大多數(shù)情況下提供良好的性能。其次使用==來(lái)實(shí)現(xiàn)相等性比較,由于 == 操作符是語(yǔ)言層面的原生操作,編譯器可以對(duì)其進(jìn)行優(yōu)化,從而提高代碼的執(zhí)行效率。

      4.2 key不可變的限制

      map鍵的不可變性也是一個(gè)考慮因素。基于==來(lái)判斷對(duì)象是否相等,間接保證了鍵的不可變性。目前,==已經(jīng)支持了大部分類(lèi)型的比較,只有自定義結(jié)構(gòu)體中的引用類(lèi)型字段無(wú)法直接使用==進(jìn)行比較。如果鍵中不存在引用類(lèi)型字段,這意味著放入Map鍵的值在運(yùn)行時(shí)不能發(fā)生變化,從而保證了鍵在運(yùn)行時(shí)的不可變性。

      如果key沒(méi)有不可變的限制,那么之前存儲(chǔ)在 map 中的鍵值對(duì)可能會(huì)出現(xiàn)問(wèn)題。因?yàn)樵诜胖迷貢r(shí),map 會(huì)根據(jù)鍵的當(dāng)前值計(jì)算哈希值,并使用哈希值來(lái)查找對(duì)應(yīng)的存儲(chǔ)位置。如果放在map中的鍵的值發(fā)生了變化,此時(shí)計(jì)算出來(lái)的hash值可能也發(fā)生變化,這意味數(shù)據(jù)放在了錯(cuò)誤的位置。后續(xù)即使使用跟map中的鍵的同一個(gè)值去查找數(shù)據(jù),也可能查找不到數(shù)據(jù)。

      下面展示一個(gè)簡(jiǎn)單的代碼,來(lái)說(shuō)明可變類(lèi)型作為key會(huì)導(dǎo)致的問(wèn)題:

      type Person struct {
          Name       string
          Age        int
          SliceField []string
      }
      
      func main() {
          person := Person{Name: "Alice", Age: 25, SliceField: []string{"A", "B"}}
          // 假設(shè)Person可以作為鍵,事實(shí)上是不支持的
          personMap := make(map[Person]string)
          personMap[person] = "Value 1"
      
          // 修改person中SliceField的值
          person.SliceField[0] = "X"
      
          // 嘗試通過(guò)相同的person查找值
          fmt.Println(personMap[person]) // 輸出空字符串,找不到對(duì)應(yīng)的值
      }
      

      如果抽取equals方法接口,由用戶(hù)自行實(shí)現(xiàn),此時(shí)key的不可變性就需要用戶(hù)實(shí)現(xiàn),其次go語(yǔ)言也需要增加一些檢測(cè)機(jī)制,這首先增加了用戶(hù)使用的負(fù)擔(dān),這并不符合go語(yǔ)言設(shè)計(jì)的哲學(xué)。

      4.3 總結(jié)

      綜上所述,基于簡(jiǎn)單性、性能和語(yǔ)義一致性的考慮以及鍵的不可變性,Go語(yǔ)言選擇使用==操作符進(jìn)行鍵的比較,而將哈希函數(shù)作為運(yùn)行時(shí)庫(kù)的默認(rèn)實(shí)現(xiàn),更加符合go語(yǔ)言設(shè)計(jì)的哲學(xué)。

      5. 總結(jié)

      在 Go 語(yǔ)言中,map 是一種無(wú)序的鍵值對(duì)集合,它提供了高效的數(shù)據(jù)存儲(chǔ)和檢索機(jī)制。在使用 map 時(shí),通常使用基本數(shù)據(jù)類(lèi)型作為鍵。然而,當(dāng)我們想要使用自定義結(jié)構(gòu)體作為鍵時(shí),需要考慮結(jié)構(gòu)體中是否包含引用類(lèi)型的字段。

      自定義結(jié)構(gòu)體作為map的鍵需要滿足一些要求。首先,鍵的類(lèi)型必須是可比較的,也就是支持通過(guò)== 運(yùn)算符進(jìn)行相等性比較。在Go中,基本數(shù)據(jù)類(lèi)型和一些內(nèi)置類(lèi)型都滿足這個(gè)要求。但是,如果結(jié)構(gòu)體中包含引用類(lèi)型的字段,那么該結(jié)構(gòu)體就不能直接作為map的鍵,因?yàn)橐妙?lèi)型不具備簡(jiǎn)單的相等性比較。

      因此總的來(lái)說(shuō),包含引用類(lèi)型字段的自定義結(jié)構(gòu)體,是不能作為mapkey的。

      posted @ 2023-06-04 14:33  菜鳥(niǎo)額  閱讀(265)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产白嫩护士在线播放| 日日猛噜噜狠狠扒开双腿小说 | 国产小嫩模无套中出视频| 高邑县| 人人妻人人爽人人添夜夜欢视频| 尹人香蕉久久99天天拍| 开心婷婷五月激情综合社区 | 国产精品免费AⅤ片在线观看| 亚洲国产成人综合熟女| 开心色怡人综合网站| 亚洲成人四虎在线播放| 正在播放酒店约少妇高潮| 精品久久综合日本久久网| 国内永久福利在线视频图片| 国产成人不卡一区二区| 亚洲av色精品一区二区| 给我播放片在线观看| 自拍偷在线精品自拍偷免费| 日本喷奶水中文字幕视频| 双乳奶水饱满少妇呻吟免费看| 亚洲少妇一区二区三区老| 亚洲国产美女精品久久久| 韩国精品一区二区三区在线观看| 国产精品色内内在线观看| 亚洲a∨无码无在线观看| 亚洲美免无码中文字幕在线| 成人福利国产午夜AV免费不卡在线 | 日本55丰满熟妇厨房伦| 国产亚洲精品aaaa片app| 四虎成人精品永久网站| 秋霞av鲁丝片一区二区| 久久毛片少妇高潮| 国产成AV人片久青草影院| 偏关县| 国产亚洲精品综合99久久| 波多野结衣在线精品视频| 亚洲天堂av日韩精品| 美国又粗又长久久性黄大片| 越南毛茸茸的少妇| 亚洲国产精品男人的天堂| 久久精品国产福利一区二区|