字典

除了内置的基本类型外,数组和字典也是内置类型

map实现

从map的源代码定义看,map是通过2个struct实现的

vlib/builtin/map.v

  1. struct map {
  2. root &mapnode //字典第一个键值对的地址
  3. element_size int //一个键值对元素占用的内存大小
  4. pub:
  5. size int //字典的大小,也就是键值对的数量,这是map唯一可以对外直接访问的属性,只读
  6. }
  7. struct mapnode { //键值对节点
  8. left &mapnode
  9. right &mapnode
  10. is_empty bool
  11. key string //键,目前只能是string类型
  12. value voidptr //值的地址,值可以是任何类型
  13. }

map定义

  1. fn main() {
  2. mut m := map[string]int{}
  3. m['one'] = 1
  4. m['two'] = 2
  5. println(m['one']) //返回对应的value
  6. println(m['bad_key']) // 如果指定key不存在,返回0
  7. }

map的key除了string类型,也可以是其他类型

string类型的key

  1. map[string]int
  2. map[string]User
  3. map[string][]int

非string类型的key

  1. module main
  2. enum Token {
  3. aa = 2
  4. bb
  5. cc
  6. }
  7. fn main() {
  8. //非字符串key
  9. // int key 整数
  10. mut m1 := map[int]int{}
  11. m1[3] = 9
  12. m1[4] = 16
  13. println(m1)
  14. // voidptr key 通用指针
  15. mut m2 := map[voidptr]string{}
  16. v := 5
  17. m2[&v] = 'var'
  18. m2[&m2] = 'map'
  19. println(m2)
  20. //rune key unicode码
  21. mut m3 := {
  22. `!`: 2 //是反引号`,不是单引号'
  23. `%`: 3
  24. }
  25. println(typeof(m3).name) // map[rune]int
  26. println(m3)
  27. // byte key 字节
  28. mut m4 := map[byte]string{}
  29. m4[byte(1)] = 'a'
  30. m4[byte(2)] = 'b'
  31. println(m4)
  32. // float key 小数
  33. mut m5 := map[f64]string{}
  34. m5[1.2] = 'a'
  35. m5[2.0] = 'b'
  36. println(m5)
  37. // enum key 枚举值
  38. mut m6 := map[Token]string{}
  39. m6[Token.aa] = 'abc'
  40. m6[Token.bb] = 'def'
  41. println(m6)
  42. }

map字面量初始化

  1. fn main() {
  2. m := map {'one':1,'two':2,'three':3}
  3. m2 := map {1 :'a', 2 :'b', 3 :'c'}
  4. println(m)
  5. println(m2)
  6. }

map.len返回字典的大小

  1. fn main() {
  2. mut m := map[string]int{}
  3. m['one'] = 1
  4. m['two'] = 2
  5. println(m.len) // 返回2
  6. }

in操作符

判断某一个元素是否包含在map的key中

  1. fn main() {
  2. mut m := map[string]int{}
  3. m['one'] = 1
  4. m['two'] = 2
  5. println('one' in m) //返回true
  6. println('three' in m) //返回false
  7. }

遍历map

  1. fn main() {
  2. mut m := map[string]int{}
  3. m['one'] = 1
  4. m['two'] = 2
  5. m['three'] = 3
  6. for key, value in m {
  7. println('key:$key,value:$value')
  8. }
  9. for key, _ in m {
  10. println('key:$key')
  11. }
  12. for _, value in m {
  13. println('value:$value')
  14. }
  15. }

访问字典成员错误处理

  1. module main
  2. fn main() {
  3. sm := {
  4. 'abc': 'xyz'
  5. }
  6. val := sm['bad_key']
  7. println(val) // 如果字典元素不存在,会返回该类型的默认值:空字符串
  8. intm := {
  9. 1: 1234
  10. 2: 5678
  11. }
  12. s := intm[3]
  13. println(s) // 如果字典元素不存在,会返回该类型的默认值:0
  14. //也可以加上or代码块来进行错误处理
  15. mm := map[string]int{}
  16. val2 := mm['bad_key'] or { panic('key not found') }
  17. println(val2)
  18. myfn()
  19. }
  20. fn myfn() ? {
  21. mm := map[string]int{}
  22. x := mm['bad_key']? //也可以本层级不处理,向上抛转错误
  23. println(x)
  24. }

if条件语句判断字典成员是否存在

  1. fn main() {
  2. mut m := {'xy': 5, 'zu': 7}
  3. mut res := []int{cap:2}
  4. for k in ['jk', 'zu'] {
  5. //检查字典m[k]是否存在,如果存在,则赋值,if条件返回true,如果不存在,则返回false
  6. if x := m[k] {
  7. res << x
  8. } else {
  9. res << -17
  10. }
  11. }
  12. println(res) //[-17,7]
  13. }

字典相关的源代码可以参考v源代码中的:vlib/builtin/map.v

更多字典相关的函数,参考标准库章节