写函数

2022-01-05 09:58:13 浏览数 (3)

函数是使用函数表达式编写的:

函数表达式: ( 参数列表选择 ) 函数返回类型选择 => 函数体 函数体:       表达式 参数列表:       固定参数列表       固定参数列表 , 可选参数列表       可选参数列表 固定参数-列表:       参数       参数 , 固定参数列表 参数:       参数名称参数类型选择 参数名称:       标识符 参数类型:       断言 函数返回类型:       断言 断言: as nullable-primiitve-type 可选参数列表:       可选参数       可选参数 , 可选参数列表 可选参数: optional 参数 可空 nullable原始类型选择原始类型_

下面是一个函数的示例,它恰好需要两个值xand y,并产生将 运算符应用于这些值的结果。该xy参数是在部分正式参数列表的功能,并且x y函数体

复制

代码语言:javascript复制
(x, y) => x   y

function-expression求值的结果是生成一个函数值(而不是对function-body求值)。作为本文档中的约定,函数值(与函数表达式相反)与形式参数列表一起显示,但使用省略号 ( ...) 而不是函数体。例如,一旦上面的函数表达式被求值,它将显示为以下函数值:

复制

代码语言:javascript复制
 (x, y) => ...

为函数值定义了以下运算符:

操作员

结果

x = y

平等的

x <> y

不相等

函数值的本机类型是自定义函数类型(派生自内在类型function),它列出参数名称并指定所有参数类型和返回类型any。(有关函数类型的详细信息,请参阅函数类型。)

调用函数

功能体的功能是通过执行调用使用的函数值invokeexpression。调用函数值意味着评估函数值的函数体并返回值或引发错误。

调用表达式:       主表达式 ( 参数列表选择 ) 参数列表:       表达式列表

每次调用函数值时,都会将一组值指定为参数列表,称为函数的参数

一个参数列表用于指定的参数固定数量直接作为表达式的列表。下面的示例在一个字段中定义一个具有函数值的记录,然后从记录的另一个字段调用该函数:

复制

代码语言:javascript复制
[ 
    MyFunction = (x, y, z) => x   y   z, 
    Result1 = MyFunction(1, 2, 3)           // 6
]

调用函数时,以下内容成立:

  • 用于评估函数的函数体的环境包括一个与每个参数对应的变量,与参数同名。每个参数对应的从所述构造的值的值的参数列表中的invokeexpression,如在限定的参数。
  • 所有与函数参数对应的表达式都会在函数体被求值之前被求值。
  • 传播计算表达式列表函数表达式中的表达式时引发的错误。
  • 参数列表构造的参数数量必须与函数的形式参数兼容,否则将引发错误并带有原因码"Expression.Error"。确定兼容性的过程在Parameters 中定义。

参数

有两种形式参数可能存在的的形式参数列表

  • 所需参数指示对应于该参数的自变量时调用的函数时,必须总是被指定。必须首先在形式参数列表中指定必需的参数。以下示例中的函数定义了必需的参数xy

复制

代码语言:javascript复制
    [ 
        MyFunction = (x, y) => x   y, 

        Result1 = MyFunction(1, 1),     // 2 
        Result2 = MyFunction(2, 2)      // 4
    ] 
  • 一个可选参数指示时调用的函数,当对应于该参数的参数可以被指定,但不要求被指定。如果在调用函数时未指定对应于可选参数的参数,则使用该值null代替。可选参数必须出现在形式参数列表中的任何必需参数之后。以下示例中的函数定义了一个固定参数x和一个可选参数y

复制

代码语言:javascript复制
    [ 
        MyFunction = fn(x, optional y) =>
                          if (y = null) x else x   y, 
        Result1 = MyFunction(1),        // 1 
        Result2 = MyFunction(1, null),  // 1 
        Result3 = MyFunction(2, 2),     // 4
    ] 

调用函数时指定的参数数量必须与形参列表兼容。A函数的一组参数的兼容性F计算如下:

  • 让值N表示A从参数列表构造的参数数量。例如:

复制

代码语言:javascript复制
    MyFunction()             // N = 0 
    MyFunction(1)            // N = 1 
    MyFunction(null)         // N = 1 
    MyFunction(null, 2)      // N = 2 
    MyFunction(1, 2, 3)      // N = 3 
    MyFunction(1, 2, null)   // N = 3 
    MyFunction(1, 2, {3, 4}) // N = 3
  • 让价值所需代表的固定参数的数量F可选的可选参数的数量F。例如:

复制

代码语言:javascript复制
()               // Required = 0, Optional = 0 
(x)              // Required = 1, Optional = 0 
(optional x)     // Required = 0, Optional = 1 
(x, optional y)  // Required = 1, Optional = 1
  • 如果满足以下条件,则参数A与函数兼容F
    • ( N >= 固定) 和 ( N <= (固定 可选))
    • 参数类型与F对应的参数类型兼容
  • 如果函数具有声明的返回类型,则函数体的结果值FF的返回类型兼容,如果以下为真:
    • 通过使用为函数参数提供的参数评估函数体所产生的值具有与返回类型兼容的类型。
  • 如果函数体产生的值与函数的返回类型不兼容,"Expression.Error"则会引发带有原因代码的错误。

递归函数

为了编写递归的函数值,需要使用作用域运算符 ( @) 来引用其作用域内的函数。例如,以下记录包含一个定义Factorial函数的字段和另一个调用它的字段:

复制

代码语言:javascript复制
[ 
    Factorial = (x) => 
                if x = 0 then 1 else x * @Factorial(x - 1), 
    Result = Factorial(3)  // 6 
]

同样,只要每个需要访问的函数都有一个名称,就可以编写相互递归的函数。在以下示例中,部分Factorial函数已重构为第二个Factorial2函数。

复制

代码语言:javascript复制
[ 
    Factorial = (x) => if x = 0 then 1 else Factorial2(x), 
    Factorial2 = (x) => x * Factorial(x - 1), 
    Result = Factorial(3)     // 6 
]

关闭

一个函数可以返回另一个函数作为值。该函数又可以依赖于原始函数的一个或多个参数。在以下示例中,与字段关联的函数MyFunction返回一个函数,该函数返回指定给它的参数:

复制

代码语言:javascript复制
[ 
    MyFunction = (x) => () => x, 
    MyFunction1 = MyFunction(1), 
    MyFunction2 = MyFunction(2), 
    Result = MyFunction1()   MyFunction2()  // 3 
]

每次调用该函数时,都会返回一个新的函数值,该值维护参数的值,以便在调用时返回参数值。

功能和环境

除了参数,所述功能体一个的函数表达式可引用存在于环境中时,功能被初始化的变量。例如,字段定义的函数MyFunction访问C封闭记录的字段A

复制

代码语言:javascript复制
[ 
A =  
    [ 
        MyFunction = () => C, 
        C = 1 
    ], 
B = A[MyFunction]()           // 1 
]

MyFunction被调用时,它访问变量的值C,即使它是B从不包含变量的环境 ( ) 中调用的C

简化声明

所述各表达为声明无类型功能服用名为单一形式参数句法速记_(下划线)。

每个表达式: each 每个表达式主体 每个表达式主体:       函数主体

简化的声明通常用于提高高阶函数调用的可读性。

例如,以下成对的声明在语义上是等效的:

复制

代码语言:javascript复制
each _   1 
(_) => _   1  
each [A] 
(_) => _[A] 
 
Table.SelectRows( aTable, each [Weight] > 12 ) 
Table.SelectRows( aTable, (_) => _[Weight] > 12 ) 

0 人点赞