You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
3.1 KiB
174 lines
3.1 KiB
function! Foo() |
|
let x = 0 |
|
function! Bar() closure |
|
let x += 1 |
|
return x |
|
endfunction |
|
return funcref('Bar') |
|
endfunction |
|
|
|
function! Goo() |
|
let x = 0 |
|
function! Bar() closure |
|
let x += 2 |
|
return x |
|
endfunction |
|
return function('Bar') |
|
endfunction |
|
|
|
" funcref 与 function 都有效 |
|
" Bar() 也是全局函数 |
|
|
|
echo 'Fn = Foo()' |
|
let Fn = Foo() |
|
echo Fn() |
|
echo Fn() |
|
echo Bar() |
|
echo Fn() |
|
|
|
" 交替使用有效 |
|
echo 'Gn = Foo()' |
|
let Gn = Goo() |
|
echo Gn() |
|
echo Gn() |
|
echo Bar() |
|
echo Gn() |
|
|
|
function! Bar() |
|
return 'Bar() redefined' |
|
endfunction |
|
|
|
echo Bar() |
|
echo Fn() |
|
echo Gn() |
|
|
|
" |
|
" 重定义对 function() 有影响,对 funcref() 影响 |
|
|
|
" 对比 s: 变量与函数 |
|
" |
|
let s:x = 0 |
|
function! s:Bar() " closure 不能放在顶层 E932 |
|
let s:x += 1 |
|
return s:x |
|
endfunction |
|
|
|
echo 's:Bar()' |
|
echo s:Bar() |
|
echo s:Bar() |
|
echo s:Bar() |
|
|
|
" 工厂函数 |
|
" 闭包独立性 |
|
" |
|
function! FGoo(base) |
|
let x = a:base |
|
function! Bar1_cf() closure |
|
let x += 1 |
|
return x |
|
endfunction |
|
function! Bar2_cf() closure |
|
let x += 2 |
|
return x |
|
endfunction |
|
return [funcref('Bar1_cf'), funcref('Bar2_cf')] |
|
endfunction |
|
|
|
echo 'FGoo(base)' |
|
let [Fn, X_] = FGoo(10) |
|
echo Fn() |
|
echo Fn() |
|
echo Fn() |
|
let [X_, Gn] = FGoo(20) |
|
echo Gn() |
|
echo Gn() |
|
echo Gn() |
|
echo Fn() |
|
echo Fn() |
|
|
|
" 偏包引用 |
|
" |
|
echo 'partial function reference' |
|
|
|
function! Full(x, y, z) |
|
echo 'Full called:' a:x a:y a:z |
|
endfunction |
|
|
|
let Part = function('Full', [3, 4]) |
|
call Part(5) |
|
echo Part |
|
" call Part() |
|
" call Part(3, 4, 5) |
|
|
|
function! FullPartial() |
|
let x = 3 |
|
let y = 4 |
|
function! Part_cf(z) closure |
|
let z = a:z |
|
return Full(x, y, z) |
|
endfunction |
|
return funcref('Part_cf') |
|
endfunction |
|
|
|
let Part = FullPartial() |
|
call Part(5) |
|
echo Part |
|
|
|
function! FuncPartial(fun, arg) |
|
" let l:arg_closure = a:arg |
|
function! Part_cf(...) closure |
|
" let l:arg_passing = a:000 |
|
" let l:arg_all = l:arg_closure + l:arg_passing |
|
return call(a:fun, a:arg + a:000) |
|
endfunction |
|
return funcref('Part_cf') |
|
endfunction |
|
|
|
let Part = FuncPartial('Full', [3, 4]) |
|
call Part(5) |
|
echo Part |
|
|
|
" lambda 表达式 |
|
" |
|
echo 'lambda expression' |
|
|
|
if 1 |
|
function! Distance(point) abort |
|
let x = a:point[0] |
|
let y = a:point[1] |
|
return x*x + y*y |
|
endfunction |
|
else |
|
let Distance = {pt -> pt[0] * pt[0] + pt[1] * pt[1]} |
|
endif |
|
|
|
" echo Distance |
|
echo Distance([3,4]) |
|
|
|
function! MaxDistance(A, B, C) abort |
|
let l:Distance = {pt -> pt[0] * pt[0] + pt[1] * pt[1]} |
|
let [A, B, C] = [a:A, a:B, a:C] |
|
let e1 = [A[0] - B[0], A[1] - B[1]] |
|
let e2 = [A[0] - C[0], A[1] - C[1]] |
|
let e3 = [B[0] - C[0], B[1] - C[1]] |
|
let d1 = Distance(e1) |
|
let d2 = l:Distance(e2) |
|
let d3 = Distance(e3) |
|
if d1 >= d2 && d1 >= d3 |
|
return d1 |
|
elseif d2 >= d1 && d2 >= d3 |
|
return d2 |
|
else |
|
return d3 |
|
endif |
|
endfunction |
|
|
|
delfunction Distance |
|
echo MaxDistance([2,8], [4,4], [5,10]) |
|
|
|
finish |
|
|
|
" |
|
" 在 MaxDistance 中调用 Distance lambda 时,须定义为局部函数引用变量 |
|
" 因 Distance() 调用只搜索 l:Distance 局部变量或全局函数,并不会搜索全局函数引 |
|
" 用变量
|
|
|