Mẫu này sẽ cho phép bạn gán tên có ý nghĩa cho từng đối số và cung cấp giá trị mặc định cho mọi đối số không được cung cấp:
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
Như được chỉ ra bởi Boris Brodski:
a:0
đếm số lượng đối số tùy chọn được thông qua
a:1
,, a:2
... chúng ta hãy truy cập các đối số tùy chọn
Các đối số bắt buộc (chỉ foo
trong ví dụ trên) không được tính
condition ? result_if_true : result_if_false
là biểu thức có điều kiện (ternary), đánh giá thuật ngữ thứ hai hoặc thứ ba tùy thuộc vào thuật ngữ đầu tiên có đúng hay không.
Vì vậy, nếu không có đối số thứ ba được cung cấp, baz
sẽ lấy giá trị mặc định là 0
.
Một mối quan tâm với ví dụ trên là a:foo
có thể chỉ được truy cập với các a:
tiền tố, trong khi bar
và baz
có thể làm mà không có một tiền tố. Vì điều này không nhất quán lắm, bạn có thể muốn rút tất cả các đối số thành các biến cục bộ, như vậy:
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
(Về mặt kỹ thuật, bạn có thể sử dụng l:
tiền tố để chỉ các biến cục bộ bên trong một hàm, chẳng hạn l:baz
, nhưng điều này là dư thừa nên tôi không khuyến nghị điều đó.)
Nhưng tôi khuyên bạn nên sử dụng mẫu này bất cứ khi nào có thể:
function! s:FunctionName(...)
Việc này !
cho phép bạn xác định lại chức năng của mình khi chạy (ví dụ: bằng cách tải lại tập lệnh) và s:
giới hạn chức năng trong phạm vi tập lệnh. Điều đó tránh gây ô nhiễm không gian tên toàn cầu (và có nguy cơ va chạm) nếu chức năng của bạn chỉ được tham chiếu từ nơi khác trong tập lệnh. Nói chung, đó là cách ưa thích để xác định các chức năng khi chúng không cần hiển thị trên toàn cầu. ;-)