函数的基本定义
在Dart中,函数也是一个对象并且属于
Function
类型。这就意味着函数可以作为变量定义或者作为其他函数的参数或者返回值
函数的定义方式:
返回值 函数的名称(参数列表) {
函数体
return 返回值
}
var name = 'world';
String sayHello(String name) {
var say = 'Hello ' + name;
return say;
}
print(sayHello(name));
如果函数中只有一个表达式,那么函数体可以使用箭头语法(arrow syntax)
String sayHello(String name) => 'Hello '+ name;
函数参数
函数的参数有两种类型必需参数(required)
和可选参数(optional)
,其中必需参数是在可选参数之前,参数的类型,出了基本类型之外,还可以是Function等类型。
可选参数
可选参数分为命名可选参数和位置可选参数
命名可选参数的演示:
// 这里的name是必传参数
void enableFlags(String name, {int age,double height}) {
}
调用的时候使用paramName: value
的方式调用,使用命名可选参数调用可以忽略参数的顺序
enableFlags("name");
enableFlags("name", age: 1);
enableFlags("name", height: 1.0,age: 1);
位置可选参数的演示:
void enableFlags(String name, [int age,bool hidden]) {
}
调用的时候,对于位置参数来说,传入的值按照定义的顺序依次赋值
enableFlags("name", 1,true);
参数默认值
无论是命名参数还是位置参数,都可以设置默认值,如果没有设置默认值,那么将采用类的默认值null
作为默认值。
- 注意, 只有可选参数才可以有默认值, 必须参数不能有默认值
// 位置可选参数
void enableFlags(String name, [bool blod = true, int hidden= 1]){
}
// 命名可选参数
void enableFlags(String name, {bool blod = true, int hidden= 1}){
//
}
函数对象
Dart可以将函数赋值给一个变量,可以作为另外一个函数的参数进行传递或者返回值来使用
main(List<String> args) {
// 1.将函数复制给一个变量
var fun = userInfo;
print(fun);
// 2.将函数作为另一个函数的参数
test(userInfo);
// 3.将函数作为另一个函数的返回值
var returnFunction = getFunction();
returnFunction('公主');
}
// 1.定义一个函数
userInfo(String name){
print('传入的name:$name');
}
// 2.将函数作为另一个函数的参数
test(Function function) {
function('王子');
}
// 3.将函数作为另一个函数的返回值
getFunction(){
return userInfo;
}
匿名函数的使用
大部分函数都包含函数名称,比如main
、和前面定义的enableFlags
函数等等。
但是在某些情况下,也可以创建一个没有名称的函数,这种函数可以被称之为:匿名函数(anonymous function)
,也可以叫做lambda
或者闭包(closure)
。
匿名函数和普通函数的定义出来没有名称以外,其他部分是相同的,
List<int> list = [1,2,3];
list.forEach((element) {
print(element);
});
// 箭头语法(箭头语法使用见上面函数基本定义)
list.forEach((int element) => print(element));
词法作用域
dart中的词法有自己明确的作用域范围,总的来说有两种作用域顶层作用域
和函数作用域
。它是根据代码结构({})
来决定作用域的范围。
优先使用自己作用域中的变量,如果没有找到,则一层层向外查找
main(List<String> args) {
bool insideMain = true;
void myFunc() {
insideMain = false;
topLevel = false;
}
}
bool topLevel = true;
void sayHello() {
print(topLevel);
// print(insideMain); // 这里会提示变量未定义
}
词法闭包
闭包可以访问其词法范围内的变量,即时函数在其他地方被使用,也能正常访问。
// 定义一个函数,接受`addBy`参数
Function makeAdder(num addBy){
// 返回出去一个匿名函数 接受参数`i`
return (num i) {
// 将 i+addBy的结果返回出去
return i + addBy;
};
}
main(List<String> args) {
// 这里的`add2`和`add4`拿到的是匿名函数方法
Function add2 = makeAdder(2);
Function add4 = makeAdder(4);
// 这里答应的是匿名函数里面执行的结果
print(add2(3));//打印结果为:5
print(add4(3));//打印结果为:7
}
如注释所写,先定义一个makeAdder
函数,其接受一个addBy
参数,然后其返回一个匿名函数,该匿名函数接受一个i
函数,在匿名函数内执行addBy+i
的操作,由于makeAdder
是匿名函数的父函数,因此在匿名函数内部可以访问父函数中定义的函数
返回值问题
所有函数都有一个返回值,如果没有指定返回值,贼语句返回null,隐式附加到函数体。
main(List<String> args) {
print(foo()); // null
}
foo() {
print('foo function');
}