Jun 的 Flutter 工坊 #1:从函数开始说起

39 阅读3分钟

一、上初中的时候,数学老师说的函数长这个样子

image.png

学生时代,老师告诉我们,函数包含三个部分: 1、函数名 2、参数 3、返回值

二、Flutter的函数定义

image.png

Flutter扩展了初中老师的概念,多了一个异步函数和同步函数的东西,异步就是async。 接下来,我们认真来学习一下函数的每个部分

三、函数名(名字是可有可无的)

  • 命名函数——顾名思义,就是有名字的函数,例如void initState() {},initState就是函数名。
  • 匿名函数——例如,() {print('Hello');},这就是一个最简单(没有返回,没有参数)的匿名函数了。
  • 为什么要有匿名函数呢?很简单,"如果一个函数只在一个地方被调用,为什么要有个名字呢?"。这种情况在函数化编程中是司空见惯的

四、函数化编程

所谓函数化编程,就是将一个函数作为另一个函数的参数(或返回值),你看下面的代码,其中 f( (){ print('hello');} );这一行,就是给一个叫做 f 的函数传入一个匿名参数作为参数

//定义一个函数f,参数是一个无参无返回值的函数callback
void f( Function() callback ) {
  callback();
}

void main() {
  //调用函数f,传入一个匿名函数作为参数,这个匿名函数会打印'hello'
  f( (){ print('hello'); });
}

五、异步函数

如果在f()后面添加了"async",那么f就是一个异步函数,异步函数有几个变化

  1. 假设函数的返回值原来是T,会自动变成了Future<T>,意思是"如果调用该函数,会立刻返回一个未来的T"
f1(){
  return "hello world";
}

f2() async{
  return "hello world";
}

void main() {
  print( f1() );
  print( f2() );
    /*
    输出结果
    hello world
    Instance of 'Future<dynamic>'
    */  
}

你如果如下这么定义f2,就会编译不过

String f2() async{ return "hello world";}

正确完整的写法是:

Future<String> f2() async{return "hello world";}
  1. 在异步函数内部,可以使用await,普通函数内部不能使用await。
f1() async{
  print("come 1");
}

void main() async{
  await f1();
  ...
  //async+await这种方式,其实是将异步的实现,模拟成同步的方式给你看
  //感觉是1个线程停下来,等待另一个线程先执行,事实上,在异步的世界里面根本就没有多线程,也根本就没有等待这回事。
}
  1. 在异步函数外部,支持.then()/.catchError()/.whenComplete()等链式调用
f1() async{
  print("come 1");
}

void main() {
  f1().then( (_){print ("come 2");} );
  print("come 3");
}

/*
输出的结果如下:
come 1
come 3
come 2
*/

六、Dart语言是面向对象的,但是不支持函数重载,只支持函数覆盖

也就是说不能有同名的函数

class A{
  f1(String s) {
    print("come $s");
  }

  f1(String s,  int i) {//编译不过,不能有两个叫做f1的函数,这一点和Java和C++等面向对象语言完全不一样
    print("come $i");
  }
}

这是因为Dart有更加牛的实现方式——可选参数

class A{
  f1(String s,[int? i]) {
    print("$s $i");
  }
}

void main() {
  A().f1('hello');
  A().f1('hello',3);
}

/*
    输出:
    hello null
    hello 3
*/

七、其他

  • Dart函数的参数,除了顺序传递之外,还能通过命名参数的方式传递,比如
class A{
  f1({required String s, int? i}) {
    print("$s $i");
  }
}

void main() {
  A().f1( s:'hello' );
  A().f1( s:"hello", i : 5 );
}
  • 以下划线开头的函数,是私有函数,就类似Java/C++里面的private

说了这么多,大家自己试一试呗,如果是完全没有经验的开发者,建议先看看Flutter起步教程,网址 docs.flutter.cn/get-started