函数在仓颉语言中是普遍存在的。通过之前的章节已经可以了解到仓颉函数的基本形式:main()函数是很多程序的入口点,func关键字用来声明函数。
本节将初步探讨函数,内容包括定义函数、函数参数、函数返回值等。在第11章还会对函数进行深入的讲解。
本节示例可以在“function_demo”应用下找到。
定义函数
仓颉使用关键字func来表示函数定义的开始,func之后依次是函数名、参数列表、可选的函数返回值类型、函数体。其中,函数名可以是任意的合法标识符,参数列表定义在一对圆括号内(多个参数间使用逗号分隔),参数列表和函数返回值类型(如果存在)之间使用冒号分隔,函数体定义在一对花括号内。
以下是一个自定义函数的示例:
// main函数是程序入口
main() {
// 执行函数
println_hello();
}
// 自定义函数
func println_hello() {
// 打印Hello World!
println("Hello World!");
}
上述示例脱胎于“Hello World”应用,只是将打印字符串的逻辑封装到了自定义函数println_hello中。上述例子执行之后输出内容如下:
Hello World!
定义函数需要注意以下几点:
- 函数名和变量名使用蛇形命名法(snake case),例如println_hello();
- 函数的位置可以随便放;
- 如果函数定义了参数,则参数都需要标注类型。
函数参数
仓颉是强类型语言,因此如果函数定义了参数,则参数都需要标注类型,例如:
// main函数是程序入口
func main() {
// 执行函数传递参数
let text = 999;
println_text(text);
}
// 如果函数定义了参数,则参数都需要标注类型
func println_text(text: Int64) {
println("text: ${text}");
}
上述例子中,println_text函数有一个参数类型是Int64。上述例子执行之后输出内容如下:
text: 999
一个函数可以拥有0个或多个参数,这些参数均定义在函数的参数列表中。根据函数调用时是否需要给定参数名,可以将参数列表中的参数分为两类:非命名参数和命名参数。
非命名参数的定义方式是p: T,其中p表示参数名,T表示参数p的类型,参数名和其类型间使用冒号连接。例如,以下add函数的两个参数a和b均为非命名参数。
func add(a: Int64, b: Int64): Int64 {
return a + b;
}
命名参数的定义方式是p!: T,与非命名参数的不同是在参数名p之后多了一个“!”。可以将上例中add函数的两个非命名参数修改为命名参数,如下所示:
func add(a!: Int64, b!: Int64): Int64 {
return a + b
}
命名参数还可以设置默认值,通过“p!: T = e”方式将参数p的默认值设置为表达式e的值。例如,可以将上述add函数的两个参数的默认值都设置为1:
func add(a!: Int64 = 1, b!: Int64 = 1): Int64 {
return a + b
}
注:只能为命名参数设置默认值,不能为非命名参数设置默认值。
参数列表中可以同时定义非命名参数和命名参数,但是需要注意的是,非命名参数只能定义在命名参数之前,也就意味着命名参数之后不能再出现非命名参数。例如,下例中add函数的参数列表定义是不合法的:
// 错误!命名参数之后不能再出现非命名参数
func add(a!: Int64, b: Int64): Int64 {
return a + b
}
上述函数会报如下错误:
error: unnamed parameters must come before named parameters
==> main.cj:39:21:
|
39 | func add(a!: Int64, b: Int64): Int64 {
| ~~~~~~~~~ ^^^^^^^^ unexpected unnamed parameter here
| |
| because it must come before this named parameter
|
1 error generated, 1 error printed.
函数参数均为不可变变量,在函数定义内不能对其赋值。
func add(a: Int64, b: Int64): Int64 {
a = a + b // 错误!
return a
}
函数参数作用域从定义处起至函数体结束:
func add(a: Int64, b: Int64): Int64 {
var a_ = a // 正确
var b = b // 错误!
return a
}
函数返回
函数返回值类型是函数被调用后得到的值的类型。函数定义时,返回值类型是可选的:可以显式地定义返回值类型(返回值类型定义在参数列表和函数体之间),也可以不定义返回值类型,交由编译器推导确定。
当显式地定义了函数返回值类型时,就要求函数体的类型、函数体中所有return e表达式中e的类型是返回值类型的子类型,否则则会因为类型不匹配而报错。
以下是一个函数返回的例子:
// main函数是程序入口
main() {
// 获取函数的返回值
let a: Int64 = 1;
let b: Int64 = 1;
let add_result = add(a, b);
println("add result: {add_result}");
}
// 定义带返回的函数
func add(a: Int64, b: Int64): Int64 {
return a + b;
}
上述例子中,add函数有两个参数类型都是Int64,该函数会返回Int64类型的值。在函数定义时如果未显式定义返回值类型,编译器将根据函数体的类型以及函数体中所有的return表达式来共同推导出函数的返回值类型。例如,上述例子中add函数的返回值类型可以被省略,但编译器仍然可以根据return a + b推导出add函数的返回值类型是Int64。
返回的值用关键字return标识。如果返回的值,是函数的最后一行,那么也可以不需要关键字return,示例如下:
// 定义带返回的函数
func add(a: Int64, b: Int64): Int64 {
// 等同于
// return a + b;
a + b
}
上述例子执行之后输出内容如下:
add result: 2
注:函数的返回值类型并不是任何情况下都可以被推导出来的,如果返回值类型推导失败,编译器会报错。指定返回类型为Unit时,编译器会在函数体中所有可能返回的地方自动插入表达式return (),使得函数的返回类型总是为Unit。
参考引用
- 免费开源书《跟老卫学仓颉编程语言开发》
- 免费开源书《跟老卫学HarmonyOS开发》
- HarmonyOS NEXT+AI大模型打造智能助手APP(仓颉版)(视频)
- 仓颉编程从入门到实践(北京大学出版社)
共同学习,写下你的评论
评论加载中...
作者其他优质文章

