2.2、Dart语言基础:函数与闭包

2021-12-14  本文已影响0人  双鱼子曰1987

学习笔记,旨在于快速入门和学习Dart,其中可能会有理解错误,请指出,一起学习。

系列文章

2.1、Dart语言基础:变量、运算符
2.2、Dart语言基础:函数与闭包
2.3、Dart语言基础:面向对象
2.4、Dart语言基础:异步
2.5、Dart语言基础:库与包
...

一、概述

void sayHello(String name) {
  print('$name say hello!');
}

// Tom say hello!
sayHello('Tom'); 

虽然可以省略参数类型和返回值类型,但是推荐最好写明白。

void sayHello(String name) => print('$name say hello!');

// Tom say hello!
sayHello('Tom'); 

二、函数参数

1、命名参数

语法格式:{param1, param2, …},如下
void introduce_1({String? name, int? age}) {
  print("$name and $age");
}

// 1、null and null
introduce_1();
// 2、null and 30
introduce_1(age: 30);
// 3、tom and 30
introduce_1(name: 'tom', age: 30);
void introduce_1_1({String? name='def', int? age}) {
  print("$name and $age");
}

// 1、def and 30
introduce_1_1(age: 30);

// 2、tom and 30
introduce_1_1(name: 'tom', age: 30);
void introduce_1_2({required String? name, int? age}) {
  print("$name and $age"); 
}

  // Error: Required named parameter 'name' must be provided.
  introduce_1_2(age: 30);  
  // tom and null
  introduce_1_2(name: 'tom');
void introduce_10({String name, int age}) {
  print("$name and $age"); 
}

// 编译器报错:类型不匹配的错误
Error: The parameter 'name' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'.
Error: The parameter 'age' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'.
语法格式2:{param1: value1, param2: value2, ...},需要指定默认值
void introduce_2({name: 'err', age: 0}) {
  print("$name and $age");
}

  // 1、err and 0
  introduce_2();
  // 2、err and 30
  introduce_2(age: 30);
  // 3、tom and 30
  introduce_2(name: 'tom', age: 30);

2、位置参数(positional parameters)

void say_1(String from, String msg) {
  print('$from says $msg');
}

  // 1、tom says hello world!
  say_1('tom', 'hello world!');
  // 2、Error: Too few positional arguments: 2 required, 1 given.
  say1('tom');
String say_1_1(String from, String msg, [String? device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

// 1、Bob says Howdy
print(say_1_1('Bob', 'Howdy')); 
// 2、Bob says Howdy with a smoke signal
print(say_1_1('Bob', 'Howdy', 'smoke signal'));
String say_1_2(String from, String msg, [String? device = 'iphone']) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}
  // 1、Bob says Howdy with a smoke signal
  print(say_1_2('Bob', 'Howdy', 'smoke signal'));
  // 2、Bob says Howdy with a iphone
  print(say_1_2('Bob', 'Howdy'));

3、默认参数值

4、一个函数可以同时定义 命名参数位置参数

void sayHelloworld_1(String name, {int? age}) {
  print("$name say hello,and age is $age!");
}
// 1、tom say hello,and age is null!
sayHelloworld_1('tom');
  
// 2、tom say hello,and age is 30!
sayHelloworld_1('tom', age: 30);

三、匿名函数,Anonymous functions

([[Type] param1[, …]]) { 
  codeBlock; 
}; 
const list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

// 输出如下:
0: apples
1: bananas
2: oranges
list.forEach(
    (item) => print('${list.indexOf(item)}: $item'));

四、作用域(词法)

1、词法作用域 Lexical scope

bool topLevel = true;

void main() {
  var insideMain = true;

  void myFunction() {
    var insideFunction = true;

    void nestedFunction() {
      var insideNestedFunction = true;

      assert(topLevel);
      assert(insideMain);
      assert(insideFunction);
      assert(insideNestedFunction);
    }
  }
}

2、词法闭包 Lexical closures

Function makeAdder(int addBy, String name) {
  return (int i) => '${addBy + i} $name';
}

  var add2 = makeAdder(2, 'aaa');
  var add4 = makeAdder(4, 'bbb');
  print(add2(3)); // 5 aaa
  print(add4(3)); // 7 bbb
上一篇 下一篇

猜你喜欢

热点阅读