我们最后要讨论的一个Vimscript变量是字典。Vimscript里的字典和Python里的dicts,Ruby里的hashes,已经javascript里的object非常相似。
字典都是通过一对大括号来创建的。字典里的值都是任意的,不过键的值基本上都是字符串。你不会认为大部分情况都是正常的,对吗?
运行下面的命令:
:echo {'a' : 1,100:'foo'}
Vim会输出{'a': 1, '100': 'foo'},你可以看到Vimscript确实把键值强制转换成字符串了,而值没有进行转换。
Vimscript避免了Javascript愚蠢的规范,它要求你在字典的末尾的元素后面加上逗号。运行下面的命令:
:echo {'a': 1, 100: 'foo',}
这次Vim还是输出了{'a': 1, '100': 'foo'}。你要记住在字典的末尾加上逗号,尤其是你的定义跨多行的时候,因为这样会在你添加新元素的时候减少出错的概率。
在一个字典中查找一个key,你可以使用和大部分语言差不多的语法。运行下面的命令:
:echo {'a': 1, '100': 'foo',}['a']
Vim会输出1。试试一个非字符串的索引:
:echo {'a': 1, '100': 'foo',}[100]
Vim会在进行查找前,先把非字符串的索引转换成字符串,这样就可以进行查找了,因为所有的键值都是字符串。
当key只由字母,数字以及下划线组成的时候,Vimscript也支持Javascript的“.”操作符进行查找。运行下面的命令:
:echo {'a': 1, '100': 'foo',}.a
:echo {'a': 1, '100': 'foo',}.100
对于上面两个场景,Vim都会输出正确的元素。怎么选择索引的方式,取决于你个人的喜好。
添加元素的操作和复制的操作一样。运行下面的命令:
:let foo = {'a', 1}
:let foo.a = 100
:let foo.b = 200
:echo foo
Vim输出{'a': 100, 'b': 200},这样就表明了复制和添加元素的操作是一样的。
Vimscript里有两种方式来从字典里删除元素。运行下面的命令:
:let test = remove(foo,'a')
:unlet foo.b
:echo foo
:echo test
Vim会输出{}和100。remove函数会把指定的键值所对应的条目删除掉,并返回删除的条目对应的值。unlet命令也可以删除字典里的条目,但是你没法使用它的值。
你不能从字典里删除不存在的条目。运行下面的命令:
:unlet foo["asdf"]
Vim会抛出错误。
对于remove和unlet的选择也是依据个人的喜好来的。如果非要做出一个选择的话,我推荐只使用remove,因为它比unlet更加灵活。remove可以做unlet所能做的所有功能,但是反过来就不成立了,如果你要保持一致的话,那就只用remove。
和列表一样,vim里有很多内置的函数用来操作字典的。运行下面的命令:
:echom get({'a':100},'a','default'}
:echom get({'a':100},'b','default'}
Vim会输出100和default,这个和list的函数一致。
你也可以通过函数来检测一个指定的键值是否在字典里。运行下面的命令:
:echom has_key({'a':100},'a')
:echom has_key({'a':100},'a')
Vim会输出1和0。记住在vim里0代表假,其他的数字代表真。
你可以通过items函数来把字典里的所有条目都取出来,运行下面的函数:
:echo items({'a':100,'b',200})
Vim会输出一个嵌套的列表,类似于[['a',100],['b',200]]。据我所知,Vimscript里的字典是无需的,所以不要期望你拿到的条目列表是有序的!
你可以用keys和values函数分别取出键值和值的列表。它们会按照你的预期来工作的——试试它们。