선택적 인수로 vimscript 함수를 만드는 방법은 무엇입니까?


33

선택적 인수가있는 함수를 만들고 싶습니다.

파이썬에서는 다음과 같이 할 것입니다 :

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에서 어떻게해야합니까?

답변:


34

예, 함수에서 선택적 인수를 사용할 수 있습니다. 파이썬의 방식만큼 편리하지는 않지만 다음과 같이하십시오.

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 테스트)
보리스 Brodski

감사합니다 @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(추가 인수 목록의 길이)에 따라 해당 인수 또는 기본값으로 설정되는 변수에 저장됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.