目录

一、Dart 是什么?

二、基础语法

1. 程序入口:main () 函数

2. 变量声明:三种方式

3. 常量:final vs const

4. 打印变量

5. 运算符:基础 + Dart 特色(空值运算符)

(1)基础运算符(和 Java/JS 一致)

(2)Dart 特色:空值运算符

6. 流程控制:if/else、循环

(1)if/else 条件判断

(2)switch case条件判断

(3)循环:for、while、forEach

三、flutter实战


一、Dart 是什么?

        Dart 是 Google 专为 Flutter 打造的强类型编程语言,也是 Flutter 唯一的开发语言。相比 Java / JavaScript,它有三个核心优势:

  • 跨端适配性:编译后可直接运行在安卓、iOS、鸿蒙等多平台,完美匹配 Flutter “一套代码多端运行” 的目标;
  • 空安全特性:从语法层面避免空指针崩溃;
  • 上手成本低:语法融合了 Java 的强类型和 JavaScript 的灵活性,有任一语言基础都能快速入门。

二、基础语法

        让我们打开上一篇中安装的 vscode 或 Trae ,创建一个以 .dart 为后缀名的文件,在这里面学习我们的基础语法,将语法学完之后,就可以配合 flutter 的组件,在 flutter 中编写代码了。

1. 程序入口:main () 函数

        Dart 所有代码的执行入口都是 main() 函数,必须有且仅有一个。

// 最基础的Dart程序结构
void main() {
  // 所有代码都写在这个函数体内

  // 输出内容到控制台,python的写法,等同于Java的System.out.println
  print("Hello Dart!"); 
}

注:

  • void 表示函数无返回值,是 main() 函数的固定写法;
  • 语句结束必须加分号 ;,Dart 严格区分大小写(比如 print 不能写成 Print)。

2. 变量声明:三种方式

        变量的声明,格式:数据类型 变量名 

        可以在声明时直接给变量赋值,格式:数据类型 变量名 = 值 ;

int a = 10;

        也可以先声明,之后赋值,格式:

                数据类型 变量名 ;

                变量名 = 值;

int b;
b = 10;
声明方式 示例 适用场景

强类型声明

(推荐)

String name = "Flutter新手"; 明确变量类型,代码易维护,减少出错
var 自动推断 var age = 20; 类型可自动推断(赋值后不可改)
dynamic 任意类型 dynamic temp = 100; 不确定变量类型(赋值后可以改变)

可空声明

类型?变量

String? name = null; 可以赋空值

注:可空变量在赋给强类型时,要使用??判空

语法: a ?? b

如果 a 不为 null,就返回 a,如果 a 为 null,就返回 b。

        具体的类型和使用方法都放到代码中进行演示

void main() {
  // 1. 强类型声明(非空,必须赋值)
  String userName = "张三"; // 字符串类型,不可为空
  int userAge = 25; // 整型,只能存整数
  double userHeight = 178.5; // 浮点型,存小数
  bool isVip = false; // 布尔型,只有true/false两个值
  
  // 错误示例:非空变量不能赋值为null
  // userName = null; // 直接报错,空安全特性限制
  
  // 2. 可空变量声明(加?表示可空)
  String? nickName = null; // 允许赋值为null
  nickName = "小张"; // 后续可修改为非空值
  
  // 3. 使用??判空
  String? name = null;  //当这个变量允许赋值为null时,赋给强类型
  String res = name ?? "默认名字"; //如果name不是null,res=name;
                                  //如果name是null,res="默认名字"
  
  // 4. var自动推断类型(赋值后类型固定)
  var phone = "13800138000"; // 自动推断为String类型
  // phone = 123; // 报错:不能将int赋值给String类型的变量
  
  // 5. dynamic任意类型(慎用)
  dynamic data = "初始值";
  data = 123; // 可随意修改类型,无报错
  data = true;
}

3. 常量:final vs const

        常量是赋值后不可修改的值,Dart 有两种常量声明方式。

void main() {
  // 1. final:运行时确定值,只能赋值一次
  final String city = getCity(); // 可通过函数赋值(运行时才知道值)
  // city = "上海"; // 报错:常量不可修改
  
  // 2. const:编译时确定值,比final更严格
  const double pi = 3.1415926; // 必须直接赋值固定值
  // const String address = getAddress(); // 报错:const不能用运行时的值
  
  // 实用场景:Flutter中定义固定尺寸、颜色常量
  const double buttonWidth = 100.0;
  const String baseUrl = "https://api.example.com";
}

// 模拟获取城市的函数
String getCity() {
  return "北京";
}

核心区别

  • final 灵活,支持运行时赋值;
  • const 更严格,必须编译时确定值。

4. 打印变量

        字符串插值:这是 Dart 中变量和字符串拼接的标准方式,语法简洁,支持所有变量类型(包括可空变量)。

核心格式

        1. 基础格式:$变量名     

        例如:"字符串内容$变量名字符串内容"

        2. 复杂格式:${表达式/变量}

        例如:"字符串内容${表达式/变量}字符串内容"

更推荐使用第二种

import 'dart:io';

void main() {
  // 普通变量
  String name = "张三";
  int age = 20;
  print("姓名:$name,年龄:$age"); // 输出:姓名:张三,年龄:20

  // 可空变量 + ?? 兜底
  String? nickName = null;
  print("昵称:${nickName ?? "匿名用户"}"); // 输出:昵称:匿名用户

  // 表达式插值(大括号内可写运算/方法)
  print("明年年龄:${age + 1}"); // 输出:明年年龄:21
  print("姓名长度:${name.length}"); // 输出:姓名长度:2
}

5. 运算符:基础 + Dart 特色(空值运算符)

(1)基础运算符(和 Java/JS 一致)

void main() {
  // 算术运算符:+ - * / %(取余)
  int a = 10, b = 3;
  print("a + b = ${a + b}"); // 13(加法)
  print("a - b = ${a - b}"); // 7(减法)
  print("a * b = ${a * b}"); // 30(乘法)
  print("a / b = ${a / b}"); // 3.333...(除法,返回浮点型)
  print("a ~/ b = ${a ~/ b}"); // 3(整数除法,只取商)
  print("a % b = ${a % b}"); // 1(取余/模运算)

  // 比较运算符:==、!=、>、<、>=、<= 返回布尔值
  print("a == b → ${a == b}"); // false(等于:判断值是否相等)
  print("a != b → ${a != b}"); // true(不等于:判断值是否不相等)
  print("a > b → ${a > b}");   // true(大于)
  print("a < b → ${a < b}");   // false(小于)
  print("a >= b → ${a >= b}"); // true(大于等于)
  print("a <= b → ${a <= b}"); // false(小于等于)

  //字符串/其他类型的比较
  String str1 = "dart";
  String str2 = "Dart";
  print("\n字符串比较:str1 == str2 → ${str1 == str2}"); // false(区分大小写)
  
  // 逻辑运算符:&&(且)、||(或)、!(非)
  bool isAdult = a > 18;       // false(10>18不成立)
  bool hasMoney = b > 0;       // true(3>0成立)
  print("isAdult && hasMoney → ${isAdult && hasMoney}"); // false(且:两边都为true才返回true)
  print("isAdult || hasMoney → ${isAdult || hasMoney}"); // true(或:只要一边为true就返回true)
  print("!isAdult → ${!isAdult}");                       // true(非:取反)
}

(2)Dart 特色:空值运算符

空值运算符是 Dart 空安全的核心,能避免 90% 的空指针问题:

void main() {
  String? nickName = null; // 可空变量
  
  // 1. ?? 空值合并
  String realName = nickName ?? "匿名用户";
  print(realName); // 输出:匿名用户
  
  // 2. ??= 空赋值
  nickName ??= "默认昵称";
  print(nickName); // 输出:默认昵称(已赋值)
  nickName ??= "新昵称";
  print(nickName); // 输出:默认昵称(非空,不赋值)
  
  // 3. ?. 空安全调用(变量非空时才执行方法)
  String? str = null;
  print(str?.length); // 输出:null(str为空,不执行length)
  str = "Flutter";
  print(str?.length); // 输出:7(str非空,执行length)
}

6. 流程控制:if/else、循环

(1)if/else 条件判断

void main() {
  int score = 85;
  if (score >= 90) {
    print("优秀");
  } else if (score >= 80) {
    print("良好");
  } else if (score >= 60) {
    print("及格");
  } else {
    print("不及格");
  }
}

(2)switch case条件判断

void main() {
  // 1. 基础示例:匹配整型值
  int week = 3;
  switch (week) {
    case 1: // 匹配值=1
      print("周一");
      break; // 必须加break,否则会执行后续case(漏break导致穿透)
    case 2:
      print("周二");
      break;
    case 3:
      print("周三");
      break;
    case 4:
    case 5: // 多个case匹配同一逻辑,无需重复写代码
      print("周中(周四/周五)");
      break;
    default: // 所有case都不匹配时执行
      print("周末");
      break;
  }

  // 2. Dart 特有:匹配字符串
  String level = "B";
  switch (level) {
    case "A":
      print("优秀");
      break;
    case "B":
      print("良好");
      break;
    case "C":
      print("及格");
      break;
    default:
      print("不及格");
      break;
  }
}

(3)循环:for、while、forEach

    List下一篇再讲,这里就把它当数组使用

void main() {
  List<String> fruits = ["苹果", "香蕉", "橙子"]; //就是String类型的数组
  
  // 1. 普通for循环(索引遍历)
  for (int i = 0; i < fruits.length; i++) {
    print("索引$i:${fruits[i]}"); // 字符串插值:用${}嵌入变量
  }
  
  // 2. for-in循环(遍历元素,推荐)
  for (String fruit in fruits) {
    print("水果:$fruit");
  }
  
  // 3. forEach循环(匿名函数,Flutter中最常用)
  fruits.forEach((String fruit) {
    print("forEach:$fruit");
  });
  
  // 4. while循环
  int count = 0;
  while (count < 3) {
    print("count:$count");
    count++;
  }
}

三、flutter实战

        Flutter 关联forEach 是 Flutter 中遍历列表渲染 Widget 的核心写法,比如:

// Flutter中用forEach渲染列表项
List<Widget> getFruitWidgets() {
  List<String> fruits = ["苹果", "香蕉", "橙子"];
  List<Widget> widgets = [];
  fruits.forEach((fruit) {
    widgets.add(Text(fruit)); // 每个水果生成一个Text组件
  });
  return widgets;
}

        现在看不懂没关系,之后用着用着就懂了,现在只是熟悉一下flutter。

        打开大家创建的flutter项目,上一篇环境搭建时让大家创建了一个项目,使用vscode或Trae打开该文件夹。

        找到 lib 文件夹下的 main.dart 文件,打开,把里面的代码全选,ctrl + ?注释掉。

        把下面的代码粘贴上去,然后web的可以直接保持运行,鸿蒙的需要打开鸿蒙模拟器运行。

        运行方法跟上一篇一样。

import 'package:flutter/material.dart';

// Flutter 程序入口(必须有)
void main() => runApp(const MyFruitApp());

// 根组件:整个App的入口组件
class MyFruitApp extends StatelessWidget {
  const MyFruitApp({super.key});

  @override
  Widget build(BuildContext context) {
    // MaterialApp 是 Flutter 基础布局框架
    return MaterialApp(
      title: '水果列表示例',
      // 主页内容
      home: Scaffold(
        // 顶部导航栏
        appBar: AppBar(
          title: const Text('forEach 渲染列表'),
          backgroundColor: Colors.blue,
        ),
        // 页面主体内容(调用我们的列表渲染方法)
        body: Center(
          // 用 Column 垂直排列列表项,更易看效果
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            // 调用 getFruitWidgets() 获取渲染后的Widget列表
            children: getFruitWidgets(),
          ),
        ),
      ),
    );
  }

  // 我们写的 getFruitWidgets 方法
  List<Widget> getFruitWidgets() {
    List<String> fruits = ["苹果", "香蕉", "橙子"];
    List<Widget> widgets = [];
    fruits.forEach((fruit) {
      // 给 Text 加样式,看得更清楚(核心是 Text(fruit))
      widgets.add(
        Text(fruit),
      );
    });
    return widgets;
  }
}

实现效果

appBar是导航栏

        在里面设置了 title(标题)为 “forEach 渲染列表”、背景颜色是蓝色。

body是页面主体

  1. 在里面放了个Center(居中)组件
  2. 在Center里面又放了个Column(垂直排列)组件,让内容垂直排列
  3. 在Column里面干了两件事,设置主要的对齐方式为:居中,调用我们写的函数
  4. 在函数里创建两个列表,一个String类型,一个Widget类型,flutter都是通过Widget类型进行显示,里面的组件都是Widget类型,所以我们的String类型列表要转换成Widget类型列表
  5. 通过forEach获取到fruits列表的每一个元素,放到fruit里面,然后把fruit设置成Text组件然后添加进widgets列表
  6. 最后返回widgets列表,这样我们在body中就能接收到整个列表,把里面的内容显示出来

也可以使用普通的for循环,只需要讲原来getFruitWidgets换成下面在段代码

  List<Widget> getFruitWidgets() {
    int a = 10;
    int b = 20;
    List<Widget> widgets = [];
    for (int i = 0; i < 5; i++) {
      widgets.add(
        Text("这是第${i + 1}个数,a=${a},b=${b},a+b=${a + b}"),
      );
      a += i; // 等同于 a = a +i
      b += i;
    }
    return widgets;
  }
}

实现效果   

将之前的内容换成了我们for循环里的内容

这样就将前面的知识稍微联系起来了

结尾

        通过本篇学习,你已经掌握了 Dart 最核心的基础语法,掌握变量、常量、流程控制、空安全基础,并且附带了flutter的演示;对于flutter看不懂没关系,慢慢来,只有先了解基础语法,才能进行项目开发。

        欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐