Як зробити функцію vimscript за допомогою необов'язкових аргументів?


35

Я хочу зробити функцію, яка має необов'язкові аргументи.

У 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?

Відповіді:


35

Так, ви можете приймати необов'язкові аргументи у функції. Це не так зручно, як це робити 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

27

Трохи запізнився на вечірку, але свого улюбленого я не побачив:

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
Я знаю, що це дуже старе, але просто FYI для тих, хто читає це. Ви більше не можете робити 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

Як вказував Борис Бродський:

a:0 підраховує кількість переданих необов'язкових аргументів

a:1, a:2... давайте доступ необов'язкові аргументи

Обов’язкові аргументи (лише fooу наведеному вище прикладі) не враховуються

condition ? result_if_true : result_if_false - це умовний (потрійний) вираз, який оцінюється на другий чи третій доданки залежно від того, чи був перший термін правдивим чи ні.

Отже, якщо третій аргумент не наводиться, bazвін прийме значення за замовчуванням 0.

Одна з проблем , з наведеним вище прикладом є те , що a:fooможе тільки бути доступні з a:префіксом, в той час як barі bazможе обійтися без префікса. Оскільки це не дуже послідовно, ви можете віддати перевагу всі аргументи в локальні змінні, наприклад:

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)
Борис Бродський

Дякую @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")і побачити, що він друкує "Привіт", "Світ", "Невизначений баз".

Для цього використовується функція varargs функцій vim, яка дозволяє передавати довільну кількість додаткових аргументів функції. Аргументи зберігаються у змінних, які залежно від 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"   

Акуратний. Вам слід розширити свою відповідь, щоб навести приклад, щоб ми могли швидко зрозуміти, що додано.
Люк Ермітт

@LucHermitte Я відповідно змінив свою відповідь.
радлан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.