如何使用可选参数制作vimscript函数?


33

我想制作一个具有可选参数的函数。

在python中,我将执行以下操作:

def functionName(arg1,arg2=false,arg3=false):
    if arg2:
        #Do stuff with arguments
    else:
        #Do stuff without arguments

我已经尝试做过function FunctionName(arg1,arg2=false,arg3=false),但是这只会给我一个错误,指出参数无效。

我该如何在vimscript中执行此操作?

Answers:


34

是的,您可以在函数中使用可选参数。它不如python那样方便,但这是您的方法:

function FooBar(...) " This is like *args in python
    echom a:0 " a:0 contains an integer which is the number of arguments passed to the function
    echom a:1 " a:1 contains the first argument passed, a:2 contains the second and so on
    echo a:000 " a:000 contains a list of all arguments that were passed to the function
endfunction

请注意,以这种方式最多只能有20个参数。

相关帮助主题:

:help :function
:help function-argument

26

晚了一点,但是我没有看到我最喜欢的人:

function! FunctionName(arg1,...)
    let arg2 = get(a:, 1, 0)
    let arg3 = get(a:, 2, 0)

    if arg2
        "Do stuff with arguments"
    else
        "Do stuff without arguments"
    endif
endfunction

其中get(a:, n, default)将得到nth可选参数返回default,如果它不存在。


哦,太好了!
joeytwiddle

3
我知道这太旧了,但仅供任何读者阅读。您不能let a:arg=在vim中做任何事情。您必须使用let l:arg=或之类的东西let arg=。见github.com/vim/vim/commit/...
jmzagorski

23

通过此模式,您可以为每个参数分配有意义的名称,并为未提供的所有参数提供默认值:

function FunctionName(foo, ...)
  let bar = a:0 >= 1 ? a:1 : 0
  let baz = a:0 >= 2 ? a:2 : 0
  ...
  " Code that makes use of a:foo, bar and baz

鲍里斯·布罗德斯基(Boris Brodski)指出:

a:0 计算传递的可选参数的数量

a:1,,a:2...让我们访问可选参数

强制参数(仅foo在上面的示例中)不计算在内

condition ? result_if_true : result_if_false 是条件(三元)表达式,其值取决于第二项或第三项是否为真。

因此,如果未提供第三个参数,baz则将采用默认值0

与上面的例子中的一个问题是,a:foo可以与被访问的a:前缀,而barbaz没有前缀可以做。由于这不是很一致,因此您可能更喜欢将所有参数都拉到局部变量中,如下所示:

function FunctionName(...)
  let foo = a:1                  " Will throw an error if no arg was provided
  let bar = a:0 >= 2 ? a:2 : 0
  let baz = a:0 >= 3 ? a:3 : 0
  ...
  " Code that makes use of foo, bar and baz

(从技术上讲,您可以使用l:前缀来引用函数内部的局部变量,例如l:baz,但这是多余的,因此我不建议这样做。)


但是我建议您尽可能使用以下表格:

function! s:FunctionName(...)

!(通过重新加载脚本如)允许您在运行时重新定义函数和s:功能上的限制脚本范围。如果仅从脚本内的其他位置引用您的函数,则可以避免污染全局名称空间(并且有发生冲突的危险)。通常,当不需要全局可见的函数时,这是定义函数的首选方法。;-)


a:0不包含固定的命名参数。a:1是第一个参数...(刚刚通过VIM 8.0测试)
Boris Brodski '18

谢谢@BorisBrodski,您说对了,很好。我已经纠正了答案。
joeytwiddle

8

我不太精通Vimscript,但这是我要这样做的方式:

function Func(foo, ...)
  if a:0 < 1
    let bar = "Unspecified bar"
  else
    let bar = a:1
  endif
  if a:0 < 2
    let baz = "Unspecified baz"
  else
    let baz = a:2
  endif

  echo a:foo
  echo bar
  echo baz
endfunction

然后call Func("Hello", "World"),您可以看到它显示“ Hello”,“ World”,“ Unspecified baz”。

这是使用vim函数的varargs功能,它使您可以向函数传递任意数量的额外参数。参数存储在变量中,该变量取决于a:0(附加参数列表的长度)被设置为其相应的参数或默认值。


2

Vim 8.1.1310开始, Vim还支持真正的可选函数参数。

但是,这意味着大多数vim安装尚不支持此功能。另外,neovim也没有提供该功能。

来自的示例:help optional-function-argument

  function Something(key, value = 10)
     echo a:key .. ": " .. a:value
  endfunction
  call Something('empty')   "empty: 10"
  call Something('key', 20) "key: 20"   

整齐。您应该扩展您的答案以举一个例子,以便我们可以快速理解它所添加的内容。
Luc Hermitte

@LucHermitte我相应地修改了答案。
拉德兰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.