function! Sum(x, y, ...) let l:sum = a:x + a:y for l:arg in a:000 let l:sum += l:arg endfor return l:sum endfunction function! Prod(x, y, ...) let l:prod = a:x * a:y for l:arg in a:000 let l:prod = l:prod * l:arg endfor return l:prod endfunction function! CalculateR(operator, ...) if a:operator ==# '+' let l:Fnr = function('Sum') elseif a:operator ==# '*' let l:Fnr = function('Prod') endif let l:result = call(l:Fnr, a:000) return l:result endfunction let s:fnrSum = function('Sum') let s:fnrProd = function('Prod') function! CalculateRs(operator, ...) if a:operator ==# '+' let l:Fnr = s:fnrSum elseif a:operator ==# '*' let l:Fnr = s:fnrProd endif let l:result = call(l:Fnr, a:000) return l:result endfunction function! s:sum(...) let l:sum = 0 for l:arg in a:000 let l:sum += l:arg endfor return l:sum endfunction function! s:prod(...) let l:prod = 1 for l:arg in a:000 let l:prod = l:prod * l:arg endfor return l:prod endfunction let s:fnrSum = function('s:sum') let s:fnrProd = function('s:prod') echo s:fnrSum(1,2,3,4) echo s:fnrProd(1,2,3,4) " let s:sum = function('s:sum') " let s:prod = function('s:prod') let s:sum = '1+2+3+4' let s:prod = '1*2*3*4' echo s:sum(1,2,3,4) echo s:prod(1,2,3,4) " 将函数引用保存在列表中 let s:operator = [function('s:sum'), function('s:prod')] function! CalculateA(...) for l:Operator in s:operator let l:result = call(l:Operator, a:000) echo l:result endfor endfunction " 将函数引用保存在字典中 let s:dOperator = {'desc': 'some function on varargins'} let s:dOperator['+'] = function('s:sum') let s:dOperator['*'] = function('s:prod') function! CalculateD(operator, ...) abort let l:Fnr = s:dOperator[a:operator] let l:result = call(l:Fnr, a:000) return l:result endfunction " 保存在成员键中 let s:dOperator.sumFnr = s:dOperator['+'] let s:dOperator.prodFnr = s:dOperator['*'] echo s:dOperator.sumFnr(1, 2, 3, 4) echo s:dOperator.prodFnr(1, 2, 3, 4) " 直接定义函数键 function s:dOperator.sum(...) let l:sum = 0 for l:arg in a:000 let l:sum += l:arg endfor return l:sum endfunction function! s:dOperator.prod(...) let l:prod = 1 for l:arg in a:000 let l:prod = l:prod * l:arg endfor return l:prod endfunction echo s:dOperator.sum(1, 2, 3, 4) echo s:dOperator.prod(1, 2, 3, 4) " 不能将字典函数引用赋值给普通函数引用 " let g:Fnr = s:dOperator.sum " echo g:Fnr(1,2,3,4) " 合法 let g:Fnr = s:dOperator.sumFnr echo g:Fnr(1,2,3,4) let s:dOperator.PI = 3.14 function! s:dOperator.area(r) return self.PI * a:r * a:r endfunction echo s:dOperator.area(2) let s:Math = {} let s:Math.PI = 3.14159 let s:Math.Area = s:dOperator.area echo s:Math.Area(2) " let g:Fnr = s:dOperator.area " echo g:Fnr(2) function! s:area(width, height) dict return a:width * a:height endfunction " echo s:area(3, 4) |" 出错 echo call('s:area', [5, 6], {}) " echo call('s:area', [5, 6]) let s:Rect = {} let s:Rect.area = function('s:area') echo s:Rect.area(3, 4) |" 正确 function! s:area() dict return self.width * self.height endfunction let s:Rect.width = 3 let s:Rect.height = 4 echo s:Rect.area() echo call('s:area', [], s:Rect) echo call(function('s:area'), [], s:Rect) " 调试信息观察 function! s:Rect.debug1() dict abort echo expand('') Hello Vim, 我在这里就是个错误 endfunction function! s:debug2() abort echo expand('') Hello Vim, 我来这里也是个错误 endfunction let s:Rect.debug2 = function('s:debug2') function! s:Rect.test() dict " abort echo expand('') call self.debug1() call self.debug2() endfunction function! s:test() abort echo expand('') call s:Rect.test() endfunction function! Test() abort echo expand('') call s:test() endfunction echo expand('') " echo s: