vlang
  • 目录
    • V语言学习笔记
    • 目录
    • 安装
    • 开发工具
    • 快速总览
    • 模块
    • 基本类型
    • 变量
    • 常量
    • 枚举
    • 数组
    • 字典
    • 流程控制
    • 函数
    • 结构体
    • 访问控制
    • 方法
    • 注解
    • 接口
    • 泛型
    • 类型别名
    • 联合类型
    • 联合体
    • 错误处理
    • 运算符重载
    • 内置json支持
    • 内置sql支持
    • 并发
    • 内存管理
    • 代码测试
    • 文档生成
    • 编译时代码
    • 包管理器
    • 单个V文件
    • V shell script
    • 不安全代码
    • 集成C代码库
    • 集成汇编代码
    • 裸机环境
    • 生成wasm
    • GUI开发
    • web开发
    • 数据库开发
  • builtin
  • strings
  • arrays
  • maps
  • datatypes
  • strconv
  • os
  • runtime
  • time
  • math
  • json
  • encoding
  • compress
  • toml
  • flag
  • term
  • log
  • io
  • readline
  • reflection
  • net
  • net.http
  • eventbus
  • regex
  • crypto
  • rand
  • sync
  • x
  • db.pg
  • db.mysql
  • db.mssql
  • db.sqlite
  • orm
  • ui
  • sokol
  • gg
  • gx
  • fontstash
  • stbi
  • clipboard
  • V抽象语法树
  • V语言服务
  • V编译器源代码
  • 生成C代码
  • 生成js代码
  • 生成go代码
  • 生成native代码
  • 解释器直接运行
  • 附录1 关键字
  • 附录2 运算符
  • 附录3 编码风格
  • 附录4 V编译器命令行使用
  • 附录5 V调试及错误定位
  • 附录6 V和Go基本语法参照
  • 附录7 V和Zig基本语法参照
由 GitBook 提供支持
在本页
  • map实现
  • map定义
  • in操作符
  • 遍历map
  • 访问字典成员错误处理
  • if条件语句判断字典成员是否存在
  • 删除字典成员

这有帮助吗?

  1. 目录

字典

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

map实现

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

vlib/builtin/map.v

pub struct map {
	// Number of bytes of a key
	key_bytes int
	// Number of bytes of a value
	value_bytes int
mut:
	// Highest even index in the hashtable
	even_index u32
	// Number of cached hashbits left for rehashing
	cached_hashbits u8
	// Used for right-shifting out used hashbits
	shift u8
	// Array storing key-values (ordered)
	key_values DenseArray
	// Pointer to meta-data:
	// - Odd indices store kv_index.
	// - Even indices store probe_count and hashbits.
	metas &u32
	// Extra metas that allows for no ranging when incrementing
	// index in the hashmap
	extra_metas     u32
	has_string_keys bool
	hash_fn         MapHashFn
	key_eq_fn       MapEqFn
	clone_fn        MapCloneFn
	free_fn         MapFreeFn
pub mut:
	// Number of key-values currently in the hashmap
	len int  //字典的大小,也就是键值对的数量,这是map唯一可以对外直接访问的属性,只读
}

struct DenseArray {
	key_bytes   int
	value_bytes int
mut:
	cap     int
	len     int
	deletes u32 // count
	// array allocated (with `cap` bytes) on first deletion
	// has non-zero element when key deleted
	all_deleted &u8 = unsafe { nil }
	keys        &u8 = unsafe { nil }
	values      &u8 = unsafe { nil }
}

map定义

fn main() {
	mut m := map[string]int{} //字面量创建字典
	m['one'] = 1 //如果key不存在,则是新增
	m['one'] = 11 //如果key存在,则是修改
	m['two'] = 2
	println(m['one']) //返回对应的value
	println(m['bad_key']) // 如果指定key不存在,返回该类型的默认值,0
}

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

string类型的key:

map[string]int
map[string]User
map[string][]int

非string类型的key:

module main

enum Token {
	aa = 2
	bb
	cc
}

fn main() {
	//非字符串key
	// int key 整数
	mut m1 := map[int]int{}
	m1[3] = 9
	m1[4] = 16
	println(m1)
	// voidptr key 通用指针
	mut m2 := map[voidptr]string{}
	v := 5
	m2[&v] = 'var'
	m2[&m2] = 'map'
	println(m2)
	// rune key unicode码
	mut m3 := {
		`!`: 2 //是反引号`,不是单引号'
		`%`: 3
	}
	println(typeof(m3).name) // map[rune]int
	println(m3)
	// u8 key 字节
	mut m4 := map[u8]string{}
	m4[u8(1)] = 'a'
	m4[u8(2)] = 'b'
	println(m4)
	// float key 小数
	mut m5 := map[f64]string{}
	m5[1.2] = 'a'
	m5[2.0] = 'b'
	println(m5)
	// enum key 枚举值
	mut m6 := map[Token]string{}
	m6[Token.aa] = 'abc'
	m6[Token.bb] = 'def'
	println(m6)
}

map字面量初始化,编译器会进行类型推断:

fn main() {
	m := {
		'one':   1
		'two':   2
		'three': 3
	}
	m2 := {
		1: 'a'
		2: 'b'
		3: 'c'
	}
	println(m)
	println(m2)
}

map.len返回字典的大小:

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

in操作符

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

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

遍历map

fn main() {
	mut m := map[string]int{}
	m['one'] = 1
	m['two'] = 2
	m['three'] = 3
	for key, value in m {
		println('key:$key,value:$value')
	}
	for key, _ in m {
		println('key:$key')
	}
	for _, value in m {
		println('value:$value')
	}
}

访问字典成员错误处理

module main

fn main() {
	sm := {
		'abc': 'xyz'
	}
	val := sm['bad_key']
	println(val) // 如果字典元素不存在,会返回该类型的默认值:空字符串
	intm := {
		1: 1234
		2: 5678
	}
	s := intm[3]
	println(s) // 如果字典元素不存在,会返回该类型的默认值:0
	//也可以加上or代码块来进行错误处理
	mut mm := map[string]int{}
	mm['abc'] = 1
	val2 := mm['bad_key'] or { panic('key not found') } //如果元素不存在,在or代码块中进行错误处理
	val3 := mm['bad_key'] or { 100 } //如果元素不存在,也可以在or代码块中返回默认值,类型必须和字典的value类型一致
	// println(val2)
	println(val3)
	if val4 := mm['abc'] { //如果元素存在,赋值成功,才执行
		println(val4)
	}
	myfn() or { panic(err) }
}

fn myfn() ! {
	mm := map[string]int{}
	x := mm['bad_key']! //也可以本层级不处理,向上抛转错误
	println(x)
}

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

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

删除字典成员

fn main() {
	mut m := map[string]int{} //字面量创建字典
	m['one'] = 1 //如果key不存在,则是新增
	m['one'] = 11 //如果key存在,则是修改
	m['two'] = 2
	println(m['two'])
	m.delete('two') //删除字典成员
	println(m['two']) //不存在返回默认值0
}

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

上一页数组下一页流程控制

最后更新于1年前

这有帮助吗?

更多字典相关的函数参考和。

内置模块
maps模块