• 【Dart】002-函数


    Dart】002-函数

    〇、学习启动器 1.0

    第一步:煮茶(茶包 + 少量茶叶)

    第二步:按摩仪按摩眼部 10 分钟;

    第三步:倒茶 + 戴上耳机听纯音乐 + 倒计时 10 分钟 + 加告诉自己随时可以停止学习

    第四步:后面每 25 分钟为一个周期,每 25 分钟休息 5 分钟,随时可以停止这个循环

    注意点:不追求学习的速度,不安排任何学习任务,随时可以停止学习!

    一、函数是什么

    0、概述

    像一个黑箱

    函数像一个黑箱,不同的输入,会通过黑箱中的逻辑处理产生一个对应的输出

    数学意义

    输入是 自变量 x , 输出是 因变量 y ,其中黑箱的处理逻辑称为对应法则 f 。三者的关系可以通过 y = f(x) 来表示。

    1、编程中的函数与方法

    强调的是功能/作用

    数学中的 函数 是强调两个 集合 间的映射关系,这对于编程中的函数而言,还是有区别的。编程中并不强制输入和输出的数量function 更强调的是 作用功能 ,其目的是完成特定的 任务,而非仅是维护映射关系。

    完成特定功能的代码段

    c/c++ 中一般称一个功能团(完成特定功能的代码段)为 函数 function ,在 java 的类中,一般称一个功能团为 方法 method 。它们都是完成特定任务的代码段。

    2、函数的定义

    dart 中,定义函数并不需要关键字。

    语法格式

    返回值类型 方法名(参数类型 参数名){
       方法体;
    }
    
    • 1
    • 2
    • 3

    简单演示

    int square(int x) {
      return x * x;
    }
    
    • 1
    • 2
    • 3

    省略 返回值类型参数类型 (不推荐)

    square(x) {
      return x * x;
    }
    
    • 1
    • 2
    • 3

    3、函数的简写:箭头函数

    当函数体中只要一行表达式时,可以通过 => 进行简写,返回表达式的值!

    闲聊*:这种写法和 ts 是一样的,java 的箭头函数是 -> ,我的日常工作中,写习惯了前端,忽然写 java 代码会不习惯。虽然我是一个以后端为主的程序员,但在前端花费的时间常常更多!

    代码演示

    int square(int x) => x * x;
    
    • 1

    二、函数的参数与调用

    0、概述

    不同的编程语言有不同的参数特性,对于 Dart 而言,支持 命名参数位置参数默认参数 ,总的来说还是比较丰富的。

    闲聊*:各种参数带来了编程的灵活性,java 在这方面我觉得就比较欠缺,很多时候我很喜欢带默认值的参数!

    1、多个参数

    代码演示

    void solution(int n, int m) {
      print("头数:$n  足数:$m");
      int y = (m - n * 2) ~/ 2;
      int x = n - y;
      print("雉数:$x  兔数:$y");
    }
    
    void main() {
      solution(35, 94);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果

    头数:35  足数:94
    雉数:23  兔数:12
    
    • 1
    • 2

    2、命名参数的作用

    语义更加明确

    它可以使 语义更加明确 ,在函数定义时,通过 {} 可以设为命名参数。

    调用函数的时候:solution(head: 35, foot: 94);

    闲聊*:确实是语义明确了,但是也增加了代码量,我在编写 java 代码时使用的 IntelliJ IDEA 是带提示的!

    void solution({
      required int head,
      required int foot,
    }) {
      print("头数:$head  足数:$foot");
      int y = (foot - head * 2) ~/ 2;
      int x = head - y;
      print("雉数:$x  兔数:$y");
    }
    
    void main() {
      solution(head: 35, foot: 94);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    无需按照参数顺序进行传递

    闲聊*:表面意思,这个好像有点用吧!毕竟都是命名参数了,只要写了肯定能对应上。

    void solution({
      required int head,
      required int foot,
    }) {
      print("头数:$head  足数:$foot");
      int y = (foot - head * 2) ~/ 2;
      int x = head - y;
      print("雉数:$x  兔数:$y");
    }
    
    void main() {
      // 不用按顺序写
      solution(foot: 94, head: 35);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3、默认参数

    概述

    在命名参数中设置参数的默认值

    语法格式

    {类型 参数名 = 默认值}
    
    • 1

    代码演示

    void solution({
      // 此处不能使用 required 关键字,都有默认值了,所以不传参数也可以
      int number = 10
    }) {
      print(number);
    }
    
    void main() {
      // 带参数调用
      solution(number: 35);
      // 不带参数调用
      solution();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果

    35
    10
    
    • 1
    • 2

    4、位置参数

    概述

    位置参数通过 [参数1,参数2,...] 来指定,其特点是必须按顺序依次进行指定若干入参。正是因为这种特性,一般来说用于参数有前后顺序的场景

    代码演示

    void main() {
      print(DateTime(1996, 4, 27));
    }
    
    • 1
    • 2
    • 3

    运行结果

    1996-04-27 00:00:00.000
    
    • 1

    三、函数类型

    0、概述

    函数可以通过 typedef 定义类型,如下定义了一个 Operation 类型,表示一种入参是 double ,返回值是 double 的函数。

    typedef Operation = double Function(double);
    
    • 1

    闲聊*:这种东西挺新的!在 ts 中有类似的东西!ts 的调用签名(我的 ts 学得并不好!)。

    1、函数对象的声明和使用

    代码演示

    // 函数类型
    typedef Operation = double Function(double);
    
    // 函数
    double square(double a) {
      return a * a;
    }
    
    main(){
      // 函数对象定义
      Operation op = square;
      // 调用函数对象:下面两种写法效果一样!
      // 和直接调用 square 函数的效果一样!
      print(op(2));
      print(op.call(2));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    运行结果

    4.0
    4.0
    
    • 1
    • 2

    有什么好处

    通过函数类型,可以让我们把函数当做 对象 来看待,这就表示 op 变量可以在编程中指代其他符合方法签名的其他函数。

    哦!方法签名!哈哈!具体使用时的强大作用,可能要在具体使用的时候去体会了!

    // 函数类型
    typedef Operation = double Function(double);
    
    // 函数
    double square(double a) {
      return a * a;
    }
    
    // 函数
    double cube(double a) {
      return a * a * a;
    }
    
    main(){
      // 函数对象定义
      Operation op = square;
      // 调用函数对象:下面两种写法效果一致
      print(op(2));
      print(op.call(2));
    
      Operation op1 = cube;
      print(op1(2));
      print(op1.call(2));
    }
    // 4.0
    // 4.0
    // 8.0
    // 8.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2、函数类型方法参数

    把函数作为其他函数的参数

    函数既然可以当做 对象 看待,那自然就可以作为函数的入参,这也是函数类型的价值体现

    其中 ? 表示该入参可为空。

    下面并不是一定要用 {} 这只是命名参数写法罢了!

    double add(double a, double b, {Operation? op}) {
      if (op == null) return a + b;
      return op(a) + op(b);
    }
    
    • 1
    • 2
    • 3
    • 4

    直接提供一个匿名函数

    直接提供一个函数,那么就不用传这个参数了!

    double add(double a, double b, op: (double e) => e * e) {
      if (op == null) return a + b;
      return op(a) + op(b);
    }
    
    • 1
    • 2
    • 3
    • 4

    完整代码演示

    // 函数类型
    typedef Operation = double Function(double);
    
    // 函数
    double square(double a) {
      return a * a;
    }
    
    // 函数
    double cube(double a) {
      return a * a * a;
    }
    
    double add(double a, double b, Operation? op) {
      if (op == null) return a + b;
      return op(a) + op(b);
    }
    
    main(){
      // 函数对象定义
      Operation op = square;
      // 调用函数对象:下面两种写法效果一致
      print(op(2));
      print(op.call(2));
    
      Operation op1 = cube;
      print(op1(2));
      print(op1.call(2));
    
      print(add(2, 4, square));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    运行结果

    4.0
    4.0
    8.0
    8.0
    20.0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、函数的作用

    函数本质上是对实现某特定功能的代码段的封装,以实现共享。这种共享有利有弊,好处在于,普通的开发者即使能力不强,也可以通过引入三方库,或者复制粘贴来完成功能需求。这就大大降低了编程中实现功能的门槛,也有利于集中人类智慧去共同解决一些问题。**弊在于,**理想很丰满,显示很骨感。就像吃大锅饭一样,这会导致很大一批人,过于依赖别人,缺乏自主思考的能力,当出现问题或找不到库时,就举步维艰。

  • 相关阅读:
    C++.I/O流
    【Spring从入门到实战】第 3 讲:Spring中Bean的注入方式
    React 入门实例教程
    我们追求的泛化,竟是一条死路?
    JumpServer开源堡垒机与爱可生云树数据库完成兼容性认证
    vuex的学习
    Graph Neural Network——图神经网络
    《java面试宝典》之事务常见面试题
    学习笔记|矩阵按键控制原理|数值转化为键码|密码锁|STC32G单片机视频开发教程(冲哥)|第十四集:矩阵按键原理及实践
    C语言字符函数和字符串函数
  • 原文地址:https://blog.csdn.net/qq_29689343/article/details/127702148