22. 函数:函数调用与返回值
在 Yaklang 中,最普通的函数定义参数其实非常简单,与其他语言的固定形参没有区别;无需声明类型即可使用;
func abc(a, b, c) { return b+1, c-1}bPlusOne, cMinusOne = abc(123, 12, 2) // bPlusOne: 13 cMinusOne: 1assert bPlusOne == 13, cMinusOne == 1
#
可变参数有时候我们在定义的时候,并不知道参数的数量应该有多少个,或者我们希望我们的函数接受多个参数,这就需要支持“可变数量”的参数了;在 Yaklang 定义下,可变数量参数定义其实非常简单,我们使用 func(a...) 中的 ... 来定义。
func sum(a...) { // typeof(a) == []var result = 0 for i in a { result += i } return result}
// 计算 1,2,3 的和assert sum(1,2,3) == 6
// 可变参数支持 0 到 n 个参数输入assert sum() == 0
同样我们也可以支持固定参数与可变参数混合的模式:
func sum(a, b...) { result = a for i in b { result += i } return result}
assert sum(12) == 12assert sum(12,3,5,6) == 12 + 3 + 5 + 6
/* 由于我们定义中包含固定形参 a 所以我们需要 1 到 n 个参数,无参数将会报错*/sum() /*这是不合理的,会报错*//*--> 17 sum()
YakVM Panic: "runtime error: function sum need at least 1 params, got 0 params"*/
#
返回值:直接返回与拆包解包与其他语言一样,我们在使用函数的时候,也会经常需要注意函数的返回值;在静态强类型语言中,函数返回值一般来说是固定的数量;但是在 Yaklang 中,函数的返回值如果不指定也是可以被接受的;实际值为 nil / undefined
#
可以没有返回值assert nil == undefined
abc = func() {}assert abc() == nilassert abc() == undefineddump(abc())
#
返回值数量可以不一定abc = func(n) { if n == 1 { return 1 } else { return 2,3,4 }}
/* abc(1) 的时候只有一个返回值 */n1 = abc(1)assert n1 == 1
/* abc(2) 有多个返回值,并且可以支持解包返回值 */r1 = abc(2)n2, n3, n4 = abc(2)println(f`abc(2) -> r1: ${r1} n2: ${n2}, n3: ${n3}, n4: ${n4}`)
/*abc(2) -> r1: [2 3 4] n2: 2, n3: 3, n4: 4*/
#
简化调用:WavyCalling在 Yaklang 中,我们新增了一个非常有趣的语法糖 WavyCalling
;这个特性指的是
通过 ~
加入函数调用的结尾,可以自动处理这个函数返回值中的错误(目前自动处理的行为是,如果这个函数结尾有错误,那么自动中断程序执行,抛出错误提示)
如下,一下两段代码是等价的
// 处理 error,但是 error 不重要,打印到屏幕即可res, err = servicescan.Scan("127.0.0.1", "443,80")if err != nil { die(err)}
// 简化上述代码后// 使用 wavy calling 来简化代码res = servicescan.Scan("127.0.0.1", "443,80")~
我们可以使用这个有意思的语法让自己编写代码更为简洁