国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

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

這篇具有很好參考價(jià)值的文章主要介紹了包含引用類型字段的自定義結(jié)構(gòu)體,能作為map的key嗎。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1. 引言

在 Go 語(yǔ)言中,map是一種內(nèi)置的數(shù)據(jù)類型,它提供了一種高效的方式來(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ù)類型,可以通過(guò)以下方式聲明和初始化:

m := make(map[keyType]valueType)

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

2. map的基本模型

了解能否將包含引用類型的自定義結(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í)鍵的類型必須支持對(duì)比操作。

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

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

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

因此,假如map中的鍵為自定義類型,同時(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)體中包含指針類型的字段,此時(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è)指針類型的字段address。創(chuàng)建了兩個(gè)對(duì)象p1p2,在我們的理解中,其是同一個(gè)對(duì)象,事實(shí)上在map中為兩個(gè)兩個(gè)互不相關(guān)的對(duì)象,主要原因都是使用地址來(lái)進(jìn)行hash計(jì)算以及相等性比較的。

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

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

當(dāng)前gomap中哈希值的計(jì)算,其提供了默認(rèn)的哈希函數(shù),不需要由用戶去實(shí)現(xiàn);其次key的相等性比較,是通過(guò)== 操作符來(lái)實(shí)現(xiàn)的,也不由用戶自定義比較函數(shù)。那我們就有一個(gè)疑問(wèn)了,為什么不抽取hashCode和equals方法接口,由用戶來(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ú)需用戶額外的實(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è)考慮因素?;?code>==來(lái)判斷對(duì)象是否相等,間接保證了鍵的不可變性。目前,==已經(jīng)支持了大部分類型的比較,只有自定義結(jié)構(gòu)體中的引用類型字段無(wú)法直接使用==進(jìn)行比較。如果鍵中不存在引用類型字段,這意味著放入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ō)明可變類型作為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方法接口,由用戶自行實(shí)現(xiàn),此時(shí)key的不可變性就需要用戶實(shí)現(xiàn),其次go語(yǔ)言也需要增加一些檢測(cè)機(jī)制,這首先增加了用戶使用的負(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ù)類型作為鍵。然而,當(dāng)我們想要使用自定義結(jié)構(gòu)體作為鍵時(shí),需要考慮結(jié)構(gòu)體中是否包含引用類型的字段。

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

因此總的來(lái)說(shuō),包含引用類型字段的自定義結(jié)構(gòu)體,是不能作為mapkey的。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-470721.html

到了這里,關(guān)于包含引用類型字段的自定義結(jié)構(gòu)體,能作為map的key嗎的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Elasticsearch教程12】Mapping字段類型之object

    首先給出結(jié)論: 在一個(gè)字段存儲(chǔ) 一個(gè) JSON對(duì)象,可以選擇 object 類型 在一個(gè)字段存儲(chǔ) 多個(gè) JSON對(duì)象,可以選擇 nested 類型 假設(shè)有一個(gè)人員信息如下: 建表時(shí)會(huì)建一個(gè)字段存一個(gè)值,它的缺點(diǎn)是字段 扁平化 , 無(wú)法直觀的表現(xiàn) 層級(jí)關(guān)系 。 字段 值 region US manager_age 30 manager_firstn

    2024年02月09日
    瀏覽(20)
  • 【Elasticsearch學(xué)習(xí)筆記二】es的Mapping字段映射、Mapping字段常用類型、Mapping映射的創(chuàng)建、查看和更新、es數(shù)據(jù)遷移、ik分詞器

    【Elasticsearch學(xué)習(xí)筆記二】es的Mapping字段映射、Mapping字段常用類型、Mapping映射的創(chuàng)建、查看和更新、es數(shù)據(jù)遷移、ik分詞器

    目錄 1、Mapping字段映射概述 2、Mapping字段常用類型 3、映射中對(duì)時(shí)間類型詳解 1)采取自動(dòng)映射器來(lái)映射 2)手工映射提前指定日期類型 4、ES的keyword的屬性ignore_above 5、Mapping映射的查看和創(chuàng)建 1)查看mapping信息:GET 索引名/_mapping 2)創(chuàng)建映射:PUT /索引名 3)?查看所有索引映

    2024年01月20日
    瀏覽(26)
  • es查詢nested字段類型數(shù)組長(zhǎng)度來(lái)判斷是否包含多個(gè)值

    使用es時(shí)經(jīng)常會(huì)碰到查詢數(shù)組格式的字段是否有多個(gè)值的情況,總結(jié)一下。 一、字段類型為keywork時(shí) 當(dāng)字段類型為keyword時(shí)(創(chuàng)建索引后,添加的第一條數(shù)據(jù)id字段格式為數(shù)組格式,便會(huì)導(dǎo)致后續(xù)的數(shù)據(jù)都是數(shù)組),查詢id字段有多值時(shí)用以下查詢語(yǔ)句: 二、字段類型為nested類型時(shí)

    2024年02月11日
    瀏覽(102)
  • 【Elasticsearch教程6】Mapping字段類型之二進(jìn)制binary

    binary類型接收一個(gè)Base64編碼的字符串,默認(rèn)情況二進(jìn)制字段 不能被存儲(chǔ)和檢索 。 binary不能被存儲(chǔ)? 這個(gè)意思不是說(shuō)沒(méi)有存儲(chǔ)在ES,而是說(shuō)mapping中該字段的store參數(shù)默認(rèn)是false。 默認(rèn)情況下字段的值都會(huì)存儲(chǔ)到 _source 里, binary 類型的值也是如此。 如果 store 屬性設(shè)置為true,

    2024年02月05日
    瀏覽(34)
  • ES索引修改mappings與重建reindex詳解之修改字段類型

    elasticsearch一直在使用,這里總結(jié)一下mappings的修改方法,分為兩種情況: 增加新的字段,這種很簡(jiǎn)單; 修改已有的字段類型,這種就比較麻煩了,需要reindex,對(duì)索引進(jìn)行遷移重建。 1.1、獲取mappings 增加一個(gè) new_stocks 字段,如下: 再查一下: 可以看到new_stocks字段已經(jīng)加上去

    2024年02月17日
    瀏覽(24)
  • 【Elasticsearch教程11】Mapping字段類型之日期時(shí)間date date_nanos

    【Elasticsearch教程11】Mapping字段類型之日期時(shí)間date date_nanos

    JSON沒(méi)有 date 類型,但我們可以把以下類型作為日期時(shí)間存入ES。 類型 說(shuō)明 字符串 日期格式的字符串,如\\\"2015-01-01\\\"或\\\"2015/01/01 12:10:30\\\" 長(zhǎng)整型 從開(kāi)始紀(jì)元(1970-01-01 00:00:00 UTC)開(kāi)始的 毫秒數(shù) 整型 從開(kāi)始紀(jì)元(1970-01-01 00:00:00 UTC)開(kāi)始的 秒數(shù) 上面的UTC(Universal Time Coordinated) 叫

    2024年01月24日
    瀏覽(25)
  • mybatisPlus返回Map類型的集合(兩列字段,一列為key,一列為value)

    1、自定義實(shí)現(xiàn)該類 2、在抽象dao層書(shū)寫(xiě)返回map集合類型的方法 3、在XXXDao.xml文件中書(shū)寫(xiě)sql語(yǔ)句和resultMap類型 4、如何使用

    2024年02月13日
    瀏覽(22)
  • 【算法與數(shù)據(jù)結(jié)構(gòu)】3 知行合一,線性查找的自定義類測(cè)試

    【算法與數(shù)據(jù)結(jié)構(gòu)】3 知行合一,線性查找的自定義類測(cè)試

    歡迎來(lái)到愛(ài)書(shū)不愛(ài)輸?shù)某绦蛟车牟┛? 本博客致力于知識(shí)分享,與更多的人進(jìn)行學(xué)習(xí)交流 本文收錄于算法與數(shù)據(jù)結(jié)構(gòu)體系專欄, 本專欄 對(duì)于0基礎(chǔ)者極為友好,歡迎與我一起完成算法與數(shù)據(jù)結(jié)構(gòu)的從0到1的跨越 ??首篇詳細(xì)講述線性查找法并且對(duì)其進(jìn)行了 初步的優(yōu)化 :??傳送門

    2023年04月27日
    瀏覽(19)
  • 使用Python爬取GooglePlay并從復(fù)雜的自定義數(shù)據(jù)結(jié)構(gòu)中實(shí)現(xiàn)解析

    【作者主頁(yè)】: 吳秋霖 【作者介紹】:Python領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、阿里云博客專家、華為云享專家。長(zhǎng)期致力于Python與爬蟲(chóng)領(lǐng)域研究與開(kāi)發(fā)工作! 【作者推薦】:對(duì)JS逆向感興趣的朋友可以關(guān)注《爬蟲(chóng)JS逆向?qū)崙?zhàn)》,對(duì)分布式爬蟲(chóng)平臺(tái)感興趣的朋友可以關(guān)注《分布式爬蟲(chóng)平臺(tái)搭建

    2024年02月04日
    瀏覽(14)
  • go 結(jié)構(gòu)體 - 值類型、引用類型 - 結(jié)構(gòu)體轉(zhuǎn)json類型 - 指針類型的種類 - 結(jié)構(gòu)體方法 - 繼承 - 多態(tài)(interface接口) - 練習(xí)

    go 結(jié)構(gòu)體 - 值類型、引用類型 - 結(jié)構(gòu)體轉(zhuǎn)json類型 - 指針類型的種類 - 結(jié)構(gòu)體方法 - 繼承 - 多態(tài)(interface接口) - 練習(xí)

    目錄 一、結(jié)構(gòu)體 1、python 與?go面向?qū)ο蟮膶?shí)現(xiàn): 2、初用GO中的結(jié)構(gòu)體:(實(shí)例化一個(gè)值類型的數(shù)據(jù)(結(jié)構(gòu)體)) 輸出結(jié)果不同的三種方式? 3、實(shí)例化一個(gè)引用類型的數(shù)據(jù)(結(jié)構(gòu)體) 4、引用類型(指針類型) vs 值類型(兩者的區(qū)別) 引用類型(指針類型) - 值類型內(nèi)存拓?fù)鋱D:

    2024年02月14日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包