İsteğe bağlı değişkenlerle vimscript işlevi nasıl yapılır?


33

İsteğe bağlı argümanlara sahip bir işlev yapmak istiyorum.

Python'da şöyle bir şey yapardım:

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

Yapmayı denedim function FunctionName(arg1,arg2=false,arg3=false), ama bu sadece geçersiz argüman söyleyerek bir hata veriyor.

Bunu vimscript'te nasıl yaparım?

Yanıtlar:


34

Evet, bir fonksiyonda isteğe bağlı argümanlar alabilir. Python'un bunu yapma şekli kadar elverişli değil, ancak bunu nasıl yapıyorsunuz:

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

Bu şekilde sadece 20'ye kadar argüman olabileceğini unutmayın.

İlgili yardım konuları:

:help :function
:help function-argument

26

Partiye biraz geç kaldım ama en sevdiğim kişiyi görmedim:

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

hangi get(a:, n, default)alacak nthdönen opsiyonel argümanı defaultmevcut değilse.


Oooh bu güzel!
joeytwiddle

3
Bunun süper eski olduğunu biliyorum, ama bunu okuyanlara FYI. let a:arg=Artık vim içinde yapamazsın . let l:arg=Ya da sadece gibi bir şey kullanmalısınız let arg=. Bakınız github.com/vim/vim/commit/…
jmzagorski

23

Bu kalıp, her bir argümana anlamlı isimler atamanıza ve verilmemiş olan argümanlar için varsayılan bir değer sunmanıza izin verir:

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'nin belirttiği gibi:

a:0 geçen isteğe bağlı argümanların sayısını sayar

a:1,, a:2... isteğe bağlı değişkenlere erişelim

Zorunlu argümanlar (sadece fooyukarıdaki örnekte) sayılmaz

condition ? result_if_true : result_if_false birinci terimin doğru olup olmamasına bağlı olarak ikinci veya üçüncü terimi değerlendiren koşullu (üçlü) ifadedir.

Yani üçüncü bir argüman sağlanmazsa, bazvarsayılan değerini alacaktır 0.

Yukarıdaki örnekte ilgili bir konu da ki a:fooolabilir ancak erişilebilir a:ederken, önek barve bazbir öneki olmadan yapabilirsiniz. Bu çok tutarlı olmadığı için, aşağıdaki gibi tüm değişkenleri yerel değişkenlere çekmeyi tercih edebilirsiniz:

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

(Teknik olarak, l:örneğin bir fonksiyon içindeki yerel değişkenlere atıfta bulunmak için önek kullanabilirsiniz l:baz, ancak bu gereksizdir, bu yüzden bunu tavsiye etmem.)


Ancak, bu formu mümkün olduğunca kullanmanız önerilir:

function! s:FunctionName(...)

!(Komut dosyası yeniden yükleyerek örneğin) çalışma zamanında sizin işlevini yeniden tanımlamak sağlar ve s:senaryo kapsamına işlevini sınırlar. Bu, işleve yalnızca komut dosyasının herhangi bir yerinden referans veriliyorsa, küresel ad alanını kirletmeyi (ve çarpışma riskini) önler. Genel olarak görünür olmaları gerekmediğinde işlevleri tanımlamak genellikle tercih edilen bir yoldur. ;-)


a:0sabit adlandırılmış parametreleri içermez. (Sadece VIM 8.0 ile test edildi) a:1içindeki ilk parametredir...
Boris Brodski

Teşekkürler @ BorisBrodski haklısın, iyi yakalamak. Cevabı düzelttim.
joeytwiddle

8

Ben vimscript içinde iyi bilgili değilim, ama bu nasıl yapardım:

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

Daha sonra call Func("Hello", "World"), "Merhaba", "Dünya", "Belirtilmemiş baz" yazdığını görebilirsiniz.

Bu, fonksiyona rastgele sayıda ekstra argüman iletmenizi sağlayan vim işlevlerinin varargs özelliğini kullanıyor. Argümanlar, a:0(ekstra argümanlar listesinin uzunluğuna bağlı olarak) bağlı olarak kendi argümanlarına veya varsayılan değere ayarlanan değişkenlerde saklanır .


2

Vim'den beri 8.1.1310 Vim, gerçek isteğe bağlı işlev değişkenlerini de destekler.

Ancak bu, çoğu vim kurulumunun henüz bunu desteklemediği anlamına gelir. Ayrıca neovim de bu özelliği sunmuyor.

Şundan örnek :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"   

Temiz. Bir örnek vermek için cevabınızı genişletmelisiniz, böylece ne eklediğini hızla kavrayabiliriz.
Luc Hermitte

@LucHermitte Cevabımı buna göre değiştirdim.
radlan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.