跳到主要内容
Varlig 指南
Varlig 首页

自定义函数

如果你一次又一次地输入同一个公式、只是换了数字,就把它变成函数吧。只需给公式和它的输入命名一次,之后在任何需要结果的地方调用它即可:小费计算器、BMI 检测、储蓄预测或发票都可以这样做。

本页介绍如何定义和调用函数、函数如何使用笔记中的其他名称、条件与递归,以及适用的限制。Varlig 自带的函数(如 sqrtround)请参阅内置函数参考

定义和调用函数

依次写出函数名、括号中的参数、等号和公式。然后按相同的顺序传入值来调用它:

calc
小费(账单, 比例) = 账单 * 比例
小费($48, 15%) 结果为 $7.20
小费($120, 12.5%) 结果为 $15.00
小费($36 + $12, 15%) 结果为 $7.20

定义行不显示结果。每次调用都会用你传入的值替换 账单比例,然后计算公式。参数可以是一整个计算式,如上面的 $36 + $12

参数是完整的值,而不只是数字,所以单位和货币会贯穿整个公式:

calc
bmi(体重, 身高) = 体重 / 身高^2
bmi(81 kg, 1.8 m) 结果为 25 kg/m²

单位会按你给出的样子保留,所以 bmi(81 kg, 180 cm) 的结果以 kg/cm² 表示。要让结果无论传入什么都使用同一单位,请在函数内部换算:

calc
bmi(体重, 身高) = (体重 / 身高^2) in kg/m^2
bmi(81 kg, 180 cm) 结果为 25 kg/m²
bmi(80 kg, 5.9 ft) 结果为 24.7375131668 kg/m²

函数也可以没有参数。定义和调用时都要写上空括号:

calc
标准税率() = 20%
£120 * 标准税率() 结果为 £24.00

普通变量(如 标准税率 = 20%)通常也能完成同样的工作,而且输入更少。

名称与参数

  • 函数名和参数名都是单个词。可以使用字母、数字和下划线,如 税后_月薪bmi2,不能有空格。如果你写成 圆 面积(r) = pi * r^2,这一行会建议你改用名称 圆_面积
  • 函数名不区分大小写:定义 BMI(体重, 身高) 后,可以调用 bmi(81 kg, 1.8 m)
  • 每个参数都需要有自己的名称。f(a, a) = a 会报错。
  • 一个函数最多可以有 32 个参数。
  • 不能重复使用内置函数的名称。round(x) = …sqrt(x) = … 会显示错误,而不会替换内置函数。普通变量仍然可以使用这些名称,如 floor = 12 m²;请参阅名称
  • 电子表格中的写法 avgtotalstdev 可以随意使用。自己定义一个 total(订单),运行的就是你的版本。
  • 函数和变量可以同名。费率 读取变量,费率(5) 则调用函数。
  • 调用函数时务必加上括号。如果单独写函数名,又没有同名变量,会显示错误。

参数中的逗号

逗号后面跟空格时用于分隔参数,逗号后面紧跟三位数字时则用于千位分组,所以你可以按平常的习惯书写金额:

calc
小费(账单, 比例) = 账单 * 比例
小费($1,200, 15%) 结果为 $180.00
小费($1200,15%) 结果为 $180.00

如果函数需要的值比按空格分出的值更多,每个逗号都会用于分隔,就像第二次调用那样。小数请使用小数点,如 小费($48, 12.5%)

使用笔记中的其他名称

函数可以使用笔记中的变量。每次调用时,它都会读取变量的当前值:

calc
增值税 = 20%
含税价(价格) = 价格 * (1 + 增值税)
含税价(£50) 结果为 £60.00
增值税 = 5%
含税价(£50) 结果为 £52.50

定义函数时变量必须已经存在,所以请把 增值税 = 20% 放在 含税价 上方。如果变量尚不存在,定义行会显示错误。

参数只在函数内部有效。名为 价格 的参数不会读取或更改笔记中其他地方名为 价格 的变量:

calc
价格 = £10
加倍(价格) = 价格 * 2
加倍(£3) 结果为 £6.00
价格 结果为 £10.00

与变量一样,在一个计算块中定义的函数,可以在同一条笔记后面的计算块中使用。Varlig 会从上到下处理笔记,所以请把函数定义在第一次调用它的行上方。位于定义上方的调用不会显示结果。

调用其他函数的函数

小函数可以层层组合:

calc
日费率 = £400
费用(天数) = 天数 * 日费率
发票(天数) = 费用(天数) * 1.2
发票(5) 结果为 £2,400.00

函数会记住定义它时已存在的辅助函数版本。如果你在下面再次定义同一个辅助函数,之前定义的函数仍然使用旧版本:

calc
运费(订单) = £4.95
总额(订单) = 订单 + 运费(订单)
运费(订单) = £2.95
总额(£30) 结果为 £34.95
运费(£30) 结果为 £2.95

要使用新的 运费,请在它下方重新定义 总额。直接修改原有定义则不会出现这种情况。Varlig 会从顶部重新计算笔记,所以下方的所有内容都会使用你修改后的版本。

函数也可以调用在它下方定义的辅助函数。这时它使用的是调用时该辅助函数的版本,所以在调用外层函数之前,辅助函数必须已经存在:

calc
结账(订单) = 订单 + 配送费(订单)
配送费(订单) = if 订单 >= £40 then £0 else £3.50
结账(£25) 结果为 £28.50
结账(£60) 结果为 £60.00

条件

使用 if … then … else … 在不同结果之间选择。如果情况多于两种,可以在 else 后面再接一个 if

calc
邮费(重量) = if 重量 <= 100 g then £0.85 else if 重量 <= 750 g then £1.55 else £3.20
邮费(90 g) 结果为 £0.85
邮费(500 g) 结果为 £1.55
邮费(1.2 kg) 结果为 £3.20

只有适用的那个分支会被计算。这样就能防止原本会失败的计算,比如除以零:

calc
人均(总额, 人数) = if 人数 > 0 then 总额 / 人数 else £0
人均(£90, 3) 结果为 £30.00
人均(£90, 0) 结果为 £0.00

递归

函数可以调用自身,只要某个条件最终能让它停下来。下面这个函数计算一群人两两握手一次的总次数:

calc
握手次数(人数) = if 人数 <= 1 then 0 else (人数 - 1) + 握手次数(人数 - 1)
握手次数(6) 结果为 15
握手次数(10) 结果为 45

每次调用都会再嵌套一层,最多允许 16 层嵌套调用。握手次数(16) 仍然有效,但 握手次数(17) 会显示 Error: calculation limit。永远到不了终止条件的函数在定义时会被接受,调用时则会触及同样的限制。两个函数也可以互相调用,同样受此限制。

日常计数使用内置函数更快,而且没有这种限制。combination(10, 2) 同样得到 45,而 factorial(n)n! 则涵盖了经典的递归示例。

列表、矩阵及其他

参数可以是列表、矩阵或复数,函数体可以使用任何内置函数:

calc
极差(成绩) = max(成绩) - min(成绩)
极差([12, 18, 9, 21]) 结果为 12

函数体中也可以包含带有自己局部变量的求和或方程求解。请参阅列表与统计求和、解方程与微积分

常见陷阱

  • ^ 书写幂。 函数中不接受 。更麻烦的是,较短的参数名可能与单位同名:在 w / h² 中, 表示平方小时,而不是参数 h。请写 w / h^2
  • 检查参数个数。 函数需要两个值时调用 小费($48) 会显示错误。
  • 一行一个公式。 定义是写在一行中的单个表达式。对于有多个步骤的计算,请为每一步定义一个小函数,再把它们组合起来。
  • 有误的重新定义会保留旧版本。 如果 小费 的新定义有错误,该行会显示错误,之前可用的 小费 仍然可以使用。
  • 笔记重新计算时结果可能改变。 每次都会重新计算调用,所以使用 random 或今天日期的函数可能会给出新的结果。
  • 错误会传递出来。 如果某个参数导致公式失败(比如除以零),调用就会显示该错误。

限制

项目 限制
每个函数的参数个数 32
嵌套调用(函数调用自身或其他函数) 16
计算一次顶层调用期间发生的调用次数 16,384
一条笔记中定义的函数个数 1,024

触及限制时会显示 Error: calculation limit。笔记的其余部分仍会正常工作。所有限制请参阅错误、诊断与限制

综合运用

下面是一份自由职业发票。日费率和增值税作为命名值放在顶部,由三个小函数完成计算:

calc
# 三月发票
日费率 = CNY 3000
增值税 = 6%
费用(天数) = 天数 * 日费率
含税价(金额) = 金额 * (1 + 增值税)
滞纳金(金额, 逾期天数) = if 逾期天数 > 30 then 金额 * 2% else CNY 0
设计 = 费用(8) 结果为 24,000.00 CNY
开发 = 费用(4.5) 结果为 13,500.00 CNY
小计 = 设计 + 开发 结果为 37,500.00 CNY
含税价(小计) 结果为 39,750.00 CNY
滞纳金(含税价(小计), 45) 结果为 795.00 CNY

修改 日费率增值税,下面的每一行都会随之更新。如果客户逾期付款,一次调用就能加上滞纳金。