六:Flutter之Dart第三节(函数)?
6.1: 函数的基本定义
Dart是一种真正的面向对象语言、所以即使函数也是对象、所有也有类型、类型就是Function
这也意味着函数可以作为变量定义或者作为其他函数的参数或者返回值
6.1.1: 函数的定义方式
返回值 函数的名称(参数列表) { 函数体 return 返回值; }
按照上面的定义方式、我们定义一个完整的函数
int sum(num num1, num num2) { return num1 + num2; }
Effective Dart 建议对公共的API、使用类型注解,但是如果我们省略掉了类型、依然是可以正常工作的。
sun(num1, num2) { return num1 + num2; }
另外,如果函数中只有一个表达式、那么可以使用箭头语法(arrow syntax)
- 注意:这里面只能是一个表达式、不能是一个语句
sum(num1, num2) => num1 + num2;
6.2: 函数的参数问题
函数的参数必须分为两类:必须参数和可选参数
前面使用的参数都是必须参数6.2.1: 可选参数
可选参数可以分为命名可选参数和位置可选参数
- 命名可选参数定义: {param1, param2, ...}
- 位置可选参数定义: [param1, param2, ...]
命名可选参数的演示:
---------------------> 命名可选参数的演示 printInfo(String name, {int age, double height}) { print('name=${name}, age=$age, height=$height'); } /* name=lishengbing, age=null, height=null name=lishengbing, age=18, height=null name=lishengbing, age=18, height=1.88 name=lishengbing, age=null, height=1.88 * */ name = lishengbing, age = null, height = null printInfo('lishengbing'); name = lishengbing, age = 18, height = null printInfo('lishengbing', age: 18); name = lishengbing, age = 18, height = 1.88 printInfo('lishengbing', age: 18, height: 1.88); name = lishengbing, age = null, height = 1.88 printInfo('lishengbing', height: 1.88);
位置可选参数的演示
---------------------> 位置可选参数的演示 定义位置可选参数 printInfo2(String name, [int age, double height]) { print('name = $name, age = $age, height = $height'); } /* name = lishengbing, age = null, height = null name = lishengbing, age = 18, height = null name = lishengbing, age = null, height = 1.88 name = lishengbing, age = 18, height = 1.88 * */ // name = lishengbing, age = null, height = null printInfo2('lishengbing'); // name = lishengbing, age = 18, height = null printInfo2('lishengbing', 18); // name = lishengbing, age = null, height = 1.88 printInfo2('lishengbing', null, 1.88); // name = lishengbing, age = 18, height = 1.88 printInfo2('lishengbing', 18, 1.88);
命名可选参数和位置可选参数区别?
- 出来写法,命名可选参数使用{} 来表示; 位置可选参数使用[]来表示
- 在调用的时候、命名可选参数可以少传、或者不对应位置传; 但是位置可选参数必须对应位置传对应参数。
6.3: 参数默认值
参数可以有默认值、在不传入的情况下、使用默认值
- 注意:只有可选参数才可以有默认值、必须参数不能有默认值
3: 参数默认值 printInfo3(String name, {int age = 18, double height = 1.99}) { print('name = $name, age = $age, height = $height'); } name = lishengbing, age = 18, height = 1.99 printInfo3('lishengbing');
Dart 的main函数就是一个接受可选的列表参数作为参数、所以在使用main函数时、我们可以传如参数、也可以不传入参数
void main() { print('返回值为void、参数可传可不传-------'); } main() { print('可选参数、可传可不传--------'); }
6.4: 函数是一等公民
在很多语言中、函数并不能作为一等公民来使用、比如java/OC、这种限制让编程不够灵活、所以现代的编程语言基本都支持函数作为一等公民来使用、Dart也支持。
这就意味着你可以将函数赋值给一个变量、也可以将函数作为另外一个函数的参数或者返回值来使用。
main(List<String> args) { // 4: 函数是一等公民 // 函数可以作为另外一个函数的参数、函数可以赋值给变量、函数可以作为另外一个函数的返回值 // 4.1: 将函数赋值给var变量 var bar = foo; //打印结果 bar=Closure: (String) => dynamic from Function 'foo': static. print(bar); // 4.2: 将函数作为另外一个函数的参数 // foo-name=lishengbing test(foo); // 4.3: 将函数作为另外一个函数的返回值 // foo-name=返回值 // type=Closure: (String) => dynamic from Function 'foo': static. var func = getFunc(); func('返回值'); print('type=${func}'); } // 定义一个函数 foo(String name) { print('foo-name=$name'); } // 将函数作为另外一个函数的参数 test(Function func) { func('lishengbing'); } // 将函数作为另外一个函数的返回值 getFunc() { return foo; }
6.5: 匿名函数的使用
大部分我们定义的函数都会有自己的名字、比如前面定义的foo、test函数等等。
但是某些情况下、给函数命名太麻烦了、我们可以使用没有名字的函数、这种函数可以被称之为匿名函数(anonymous function),也可以叫lambda或者closure
5: 匿名函数的使用 5.1: 定义数组 var movies = ['星际穿越', '星际迷航', '普罗米修斯', '美国队长5']; 5.2: 使用forEach遍历:有名字的函数 printElement(item) { print('item=$item'); } item=星际穿越 item=星际迷航 item=普罗米修斯 item=美国队长5 movies.forEach(printElement); 5.3: 使用forEach遍历: 匿名函数 匿名函数遍历打印=星际穿越 匿名函数遍历打印=星际迷航 匿名函数遍历打印=普罗米修斯 匿名函数遍历打印=美国队长5 movies.forEach((item) { print('匿名函数遍历打印=$item'); }); print('-----------'); 匿名函数遍历写法二打印=星际穿越 匿名函数遍历写法二打印=星际迷航 匿名函数遍历写法二打印=普罗米修斯 匿名函数遍历写法二打印=美国队长5 movies.forEach((item) => print('匿名函数遍历写法二打印=$item'));
6.6: 词法作用域
Dart中的词法有自己明确的作用范围、它是根据代码的结构({})来决定作用域范围的。
优先使用自己作用域的变量、如果没有找到、则一层层想外找 。
var name = 'global'; //3-------------> 如果其他地方都没有定义name,就打印global这个 name=global main(List<String> args) { //2----------->如果函数里面没有就打印这个 name=main //var name = 'main'; foo() { //var name = 'foo'; //1---------->如果内部有就打印这个 name=foo print('name=$name'); } foo(); }
6.7: 词法闭包
闭包可以访问其词法范围内的变量、即使函数在其他地方被使用、也可以正常的访问。
makeAdder(num addby) { return (num i) { return i + addby; }; } var adder2 = makeAdder(2); // 12 print('adder2----1=${adder2(10)}'); // 8 print(adder2(6)); var adder5 = makeAdder(5); // 15 print(adder5(10)); // 11 print(adder5(6));
6.8: 返回值问题
所有函数都返回一个值、如果没有指定的返回值、则语句返回null; 隐式附加到到函数体中。
// 8: 返回值问题 main(List<String> args) { // foo2----- // null print(foo2()); } foo2() { print("foo2-----"); }