功能
函数是编程的基本构建块 —— 它们是对执行任务的语句进行分组的一种方便而强大的方法。它们是 NetScaler 设备和扩展代码之间的接口。对于策略,您可以定义策略扩展功能。对于协议,您可以为协议行为实现回调函数。函数由函数定义组成,这些定义指定传入和传出函数的值以及为函数运行哪些语句;函数调用,函数调用运行具有特定输入数据的函数并从函数中获取结果。
协议行为回调函数
TCP 客户端行为由处理 TCP 客户端数据流事件的回调函数 (on_data) 组成。要为基于 TCP 的协议实现基于消息的负载平衡 (MBLB),您可以为此回调函数添加代码,以处理来自客户端的 TCP 数据流并将字节流解析为协议消息。
行为中的回调函数是通过上下文调用的,上下文是处理模块状态。上下文是处理模块的实例。例如,对于不同的客户端 TCP 连接,使用不同的上下文调用 TCP 客户端行为回调。
除了上下文之外,行为回调还可以有其他参数。通常,其余的参数作为有效载荷传递,这是所有参数的集合。因此,可编程处理模块实例可以看作是实例状态加上事件回调函数的组合,即上下文加行为。流量作为事件有效载荷通过管道。
TCP 客户端回调函数的原型:
Function client on_data (ctxt, payload)
//.code
end
<!--NeedCopy-->
其中,
- ctxt -TCP 客户端处理上下文
- 有效载荷 -事件负载
- payload.data-接收的 TCP 数据,以字节流的形式提供
策略扩展功能
由于键入了 NetScaler 策略表达式语言,因此扩展函数的定义必须指定其输入的类型和返回值。L ua 函数 定义已扩展为包括以下类型:
function self-type: function-name(parameter1: parameter1-type, and so on): return-type
statements
end
<!--NeedCopy-->
其中,
这些类型是 NSTEXT、NSNUM、NSBOOL 或 NSDOUBLE。
Sself-type 是传递给函数的隐式自身参数的类型。在 NetScaler 策略表达式中使用扩展函数时,这是函数左侧的表达式生成的值。另一种查看方法是,该函数在 NetScaler 策略语言中扩展了该类型。
参数类型是策略表达式中扩展函数调用中指定的每个参数的类型。扩展函数可以有零个或多个参数。
return 类型是扩展函数调用返回的值的类型。它是函数右侧策略表达式部分(如果有)的输入,否则是表达式结果的值。
示例:
function NSTEXT:COMBINE_HEADERS() : NSTEXT
在策略表达式中使用扩展功能:
HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1\r\n").COMBINE_HEADERS()
这里的自我参数是的结果 HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1\r\n")
,这是一个文本值。COMBINE_HEADERS () 调用的结果是文本,并且由于此调用右侧没有任何内容,因此整个表达式的结果为文本。
局部函数定义
除了扩展函数之外,扩展文件中不能定义全局函数。但是局部函数可以使用普通的 Lua 函数语句在扩展函数中定义。这会声明函数的名称及其参数的名称(也称为参数),并且像 Lua 中的所有声明一样,不指定任何类型。这样做的语法是:
local function function-name(parameter1-name, parameter2-name, and so on)
statements
end
<!--NeedCopy-->
函数和参数名称都是标识符。(函数名实际上是一个变量,函数语句是局部函数名 = function(参数1 等)的简写,但是您不必理解这种微妙之处就可以使用函数。)
请注意,这里使用等等来延续参数名称的模式,而不是通常的…。这是因为… 本身实际上意味着一个变量参数列表,这里不会讨论。
函数体和返回
函数和 end 语句之间的语句块是函数体。在函数体中,函数参数的作用类似于局部变量,其值由函数调用提供,如前所述。
return 语句提供要返回给函数调用者的值。它必须出现在块的末尾(在函数中,如果是,for 循环等)。它可以在自己的区块中返回… 结束)。它指定没有、一个或多个返回值:
return -- returns nil
return expression -- one return value
return expression1, expression2, ... -- multiple return values
<!--NeedCopy-->
示例:
local function fsum(a)
local sum = 0
for i = 1, #a do
sum = sum + a[i]
end
return sum
end
Local function fsum_and_average(a)
local sum = 0
for i = 1, #a do
sum = sum + a[i]
end
return sum, sum/#a
end
<!--NeedCopy-->
函数调用
函数调用运行函数的主体,为函数的参数提供值并接收结果。函数调用的语法是函数名称(expression 1、expression 2 等),其中函数参数被设置为相应的表达式。表达式和参数的数量不必相同。如果表达式少于参数,则剩余的参数将设置为 nil。因此,您可以在调用结束时将一个或多个参数设置为可选参数,然后您的函数可以通过检查它们是否为 nil 来检查它们是否被指定。执行此操作的常见方法是使用 OR 操作:
function f(p1, p2) -- p2 is optional
p2 = p2 or 0 -- if p2 is nil, set to a default of 0
. . .
end
<!--NeedCopy-->
如果表达式多于参数,则会忽略剩余的表达式值。
如前所述,函数可以返回多个值。这些返回值可以在多重赋值语句中使用。示例:
local my_array = {1, 2, 3, 4}
local my_sum, my_ave = sum_and_average(my_array)
<!--NeedCopy-->
迭代器函数和泛型 for 循环
现在我们已经引入了函数,我们可以谈谈泛型 for 循环。泛型 for 循环(包含一个变量)的语法为:
for variable in iterator(parameter1, parameter2, and so on) do
statements in the for loop body
end
<!--NeedCopy-->
其中 iterator () 是一个具有零个或多个参数的函数,这些参数在循环体的每次迭代中为变量提供一个值。迭代器函数使用一种叫做闭包的技术来跟踪它在迭代中的位置,在这里您不必担心。它通过返回 nil 来表示迭代结束。迭代器函数可以返回多个值,用于多重赋值。
编写迭代器函数超出了本文的范围,但是很少有用的内置迭代器来说明这个概念。一个是 pairs () 迭代器,它遍历表中的条目并返回两个值,即键和下一个条目的值。
示例:
local t = {k1 = "v1", k2 = "v2", k3 = "v3"}
local a = {} -- array to accumulate key-value pairs
local n = 0 -- number of key-value pairs
for key, value in pairs(t) do
n = n + 1
a[n] = key.. " = ".. Value -- add key-value pair to the array
end
local s = table.concat(a, ";") -- concatenate all key-value pairs into one string
<!--NeedCopy-->
另一个有用的迭代器是 string.gmatch()
函数,它在下面的 COMBINE_HEADERS()
示例中使用。