关于Skill的自定义函数
定义方法:
a. 大部分自定义函数用procedure就够了,如:
procedure( trAdd( x y ) printf( "Adding %d and %d ... %d \n" x y x+y ) x+y ) => trAdd 定义函数trAdd trAdd( 6 7 ) => 13 调用函数trAdd
b. lambda用来定义一个没有函数名的函数,它在一些很小的函数里很方便,例如:
signalList = '( ( nil strength 1.5 ) ( nil strength 0.4 ) ( nil strength 2.5 ) ) sort( signalList 'lambda( ( a b ) a->strength <= b->strength ) ;定义一个用来按signalList的strength属性排序的内置函数,它没有具体的函数名 )
参数:函数的参数是在调用函数时用来传递一定的参数,Skill的参数除了基本的参数传递功能外,还有其他的@option来控制参数传递的方法:
@rest, 调用函数时允许任意多个参数传递给函数,
procedure( trTrace( fun @rest args ) let( ( result ) printf( "\nCalling %s passing %L" fun args ) result = apply( fun args ) printf( "\nReturning from %s with %L\n" fun result ) result ) ; let ) ; procedure
调用函数及返回结果:
trTrace( 'plus 1 2 3 ) => 6 ;返回值 =>Calling plus passing (1 2 3) Returning from plus with 6
@optional, 可以传递一个可选参数,否则会用默认值,
procedure( trBuildBBox( height width @optional ( xCoord 0 ) ( yCoord 0 ) ) list( xCoord:yCoord ;;; lower left xCoord+width:yCoord+height ) ;;; upper right ) ; procedure
调用函数及返回结果:
trBuildBBox( 1 2 ) => ((0 0) (2 1)) trBuildBBox( 1 2 4 ) => ((4 0) (6 1)) trBuildBBox( 1 2 4 10) => ((4 10) (6 11))
@key,可以指定参数是如何传递的,应此调用是参数的顺序不固定
procedure( trBuildBBox( @key ( height 0 ) ( width 0 ) ( xCoord 0 ) ( yCoord 0 ) ) list( xCoord:yCoord ;;; lower left xCoord+width:yCoord+height ) ;;; upper right ) ; procedure trBuildBBox() => ((0 0) (0 0)) trBuildBBox( ?height 10 ) => ((0 0) (0 10)) trBuildBBox( ?width 5 ?xCoord 10 ) => ((10 0) (15 0))
其中@key和@optional不能同时出现在一个函数的定义中,另外的情况可以组合在一起:
procedure(functionname([var1 var2 ...] [@optional opt1 opt2 ...] [@rest r]) .. )
procedure(functionname([var1 var2 ...] [@key key1 key2 ...] [@rest r]) .. )
局部变量, Skill中的变量默认都是全局变量,为了避免命名冲突,要尽量减少全局变量的使用,而采用局部变量。Skill可以用let和prog定义局部变量,如下面的例子:
procedure( trGetBBoxHeight( bBox ) let( ( ( ll car( bBox ) ) ( ur cadr( bBox ) ) lly ury ) lly = cadr( ll ) ury = cadr( ur ) ury - lly ) ; let ) ; procedure
局部变量默认初始化为nil,当然也可以初始化为别的值或表达式,表达式中不能有别的局部变量,prog和let的区别在于,prog支持函数go和return,可以显示的循环和返回多个值,而let返回值是最后一个表达式的值,例子的返回值是ury – lly. 除了有必要用prog,一般用let,更加简洁快速。
网友留言: