亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang 如何獲取map所有key的方式

 更新時間:2021年04月25日 09:22:33   作者:YZF_Kevin  
這篇文章主要介紹了golang 獲取map所有key的方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

最佳方式:根據map的長度,新建一個數組,遍歷map逐個壓入

方法1(效率很高):

func getKeys1(m map[int]int) []int {
 // 數組默認長度為map長度,后面append時,不需要重新申請內存和拷貝,效率很高
 j := 0
 keys := make([]int, len(m))
 for k := range m {
  keys[j] = k
  j++
 }
 return keys
}

方法2(效率很高):

func getKeys2(m map[int]int) []int {
 // 數組默認長度為map長度,后面append時,不需要重新申請內存和拷貝,效率很高
 keys := make([]int, 0, len(m))
 for k := range m {
  keys = append(keys, k)
 }
 return keys
}

其他方式:

方法3(效率較低):

func getKeys3(m map[int]int) []int {
 // 注意:由于數組默認長度為0,后面append時,需要重新申請內存和拷貝,所以效率較低
 keys := []int{}
 for k := range m {
  keys = append(keys, k)
 }
 return keys
}

方法4(效率極低):

func getKeys4(m map[int]int) int {
 // 注意:雖然此寫法簡潔,但MapKeys函數內部操作復雜,效率極低
 keys := reflect.ValueOf(m).MapKeys()
 return len(keys)
}

實驗結果如圖(可以看到方法1和方法2效率最高,內存操作也最少):

完整代碼如下:

package test
 
import (
 "reflect"
 "testing"
)
 
// 初始化map
func initMap() map[int]int {
 m := map[int]int{}
 for i := 0; i < 10000; i++ {
  m[i] = i
 }
 return m
}
 
func getKeys1(m map[int]int) []int {
 // 數組默認長度為map長度,后面append時,不需要重新申請內存和拷貝,效率較高
 j := 0
 keys := make([]int, len(m))
 for k := range m {
  keys[j] = k
  j++
 }
 return keys
}
 
func getKeys2(m map[int]int) []int {
 // 數組默認長度為map長度,后面append時,不需要重新申請內存和拷貝,效率較高
 keys := make([]int, 0, len(m))
 for k := range m {
  keys = append(keys, k)
 }
 return keys
}
 
// 初始化默認
func getKeys3(m map[int]int) []int {
 // 注意:由于數組默認長度為0,后面append時,需要重新申請內存和拷貝,所以效率較低
 keys := []int{}
 for k := range m {
  keys = append(keys, k)
 }
 return keys
}
 
// 使用反射
func getKeys4(m map[int]int) int {
 // 注意:雖然此寫法簡潔,但MapKeys函數內部操作復雜,效率極低
 keys := reflect.ValueOf(m).MapKeys()
 return len(keys)
}
 
func BenchmarkMapkeys1(b *testing.B) {
 // 初始化map
 m := initMap()
 
 b.ResetTimer()
 for i := 0; i < b.N; i++ {
  getKeys1(m)
 }
}
func BenchmarkMapkeys2(b *testing.B) {
 // 初始化map
 m := initMap()
 
 b.ResetTimer()
 for i := 0; i < b.N; i++ {
  getKeys2(m)
 }
}
 
func BenchmarkMapkeys3(b *testing.B) {
 // 初始化map
 m := initMap()
 
 b.ResetTimer()
 for i := 0; i < b.N; i++ {
  getKeys3(m)
 }
}
 
func BenchmarkMapkeys4(b *testing.B) {
 // 初始化map
 m := initMap()
 
 b.ResetTimer()
 for i := 0; i < b.N; i++ {
  getKeys4(m)
 }
}

補充:Golang踩坑——判斷map中是否有key

最近在實習,下班回去十點多了,再加上比較懶,快有兩個月沒寫東西了。

今天在開發(fā)一個模塊的時候是接著上一個人的寫的,好不容易各種配置寫好了開始跑,發(fā)現(xiàn)他踩了一個很容易踩的坑。

把bug抽出來單獨寫了個文件

package main
 
import (
	"log"
)
 
type agent struct {
	id  int
	str string
}
 
var m map[int]*agent 
func main() {
	m = make(map[int]*agent)
	a := &agent{
		id:  1,
		str: "hello",
	}
	log.Println(a)
	var ok bool
	if a, ok = m[1]; ok {
		log.Println("ok")
	}
	m[1] = a
	log.Println(a)
	log.Println(a.str)
}

運行一下

可以看到報了無效指針的問題(invalid memory address or nil pointer dereference)。

從上面的兩個log可以看到,最開始指針是有值的,第二個卻沒了,原因就出現(xiàn)在那個if判斷那里。

if判斷是想通過查看map知道agent是否已經存在,這個地方的錯誤是a,ok = map; 我們想通過ok判斷是否存在,但是在這里還有個a,這會導致有一個對a賦值的操作,也就是說如果map里有這個值,那沒事,如果沒有的話a就被賦值成了nil了。

在下面打印的時候也就成了nil,取它的屬性的時候會告訴我們找了個空指針的屬性,這肯定找不到。

我們把a換成_,再來看結果:

ok了。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關文章

  • Golang Gorm 更新字段save、update、updates

    Golang Gorm 更新字段save、update、updates

    在gorm中,批量更新操作可以通過使用Update方法來實現(xiàn),本文主要介紹了Golang Gorm 更新字段save、update、updates,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • 使用docker構建golang線上部署環(huán)境的步驟詳解

    使用docker構建golang線上部署環(huán)境的步驟詳解

    這篇文章主要介紹了使用docker構建golang線上部署環(huán)境的步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-11-11
  • Go 1.18新特性之泛型的全面講解

    Go 1.18新特性之泛型的全面講解

    本文力求能讓未接觸過泛型編程的人也能較好理解Go的泛型,所以行文可能略顯啰嗦。但是請相信我,看完這篇文章你能獲得對Go泛型非常全面的了解
    2023-03-03
  • Go語言sync.Cond使用方法詳解

    Go語言sync.Cond使用方法詳解

    Go語言標準庫中還包含條件變量 sync.Cond,它可以讓一組 Goroutine 都在滿足特定條件時被喚醒,每一個sync.Cond結構體在初始化時都需要傳入一個互斥鎖,接下來我們將通過文中例子了解它的使用方法,感興趣的同學跟著小編一起來看看吧
    2023-07-07
  • Go習慣用法(多值賦值短變量聲明賦值簡寫模式)基礎實例

    Go習慣用法(多值賦值短變量聲明賦值簡寫模式)基礎實例

    本文為大家介紹了Go習慣用法(多值賦值,短變量聲明和賦值,簡寫模式、多值返回函數、comma,ok 表達式、傳值規(guī)則)的基礎實例,幫大家鞏固扎實Go語言基礎
    2024-01-01
  • Golang設計模式之外觀模式講解和代碼示例

    Golang設計模式之外觀模式講解和代碼示例

    外觀是一種結構型設計模式, 能為復雜系統(tǒng)、 程序庫或框架提供一個簡單 (但有限) 的接口,這篇文章就給大家詳細介紹一下Golang的外觀模式,文中有詳細的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-06-06
  • vim配置go語言語法高亮問題的解決方法

    vim配置go語言語法高亮問題的解決方法

    vim配置go語言語法高亮的問題已經遇到過好幾次了,每次都是找不到答案,今天小編給大家?guī)砹藇im配置go語言語法高亮問題的解決方法,感興趣的朋友一起看看吧
    2018-01-01
  • 詳解golang中接口使用的最佳時機

    詳解golang中接口使用的最佳時機

    接口在系統(tǒng)設計中,以及代碼重構優(yōu)化中,是一個不可或缺的工具,能夠幫助我們寫出可擴展,可維護性更強的程序,本文主要為大家介紹一下golang中接口使用的最佳時機,有興趣的可以了解下
    2023-09-09
  • golang中json和struct的使用說明

    golang中json和struct的使用說明

    這篇文章主要介紹了golang中json和struct的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go中的fuzz模糊測試使用實戰(zhàn)詳解

    Go中的fuzz模糊測試使用實戰(zhàn)詳解

    這篇文章主要為大家介紹了Go中的fuzz模糊測試使用實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12

最新評論