在 Dart 中,变量是用来存储数据值的命名空间。每个变量都有一个类型,它决定了变量可以存储的数据种类。Dart 是一种强类型语言,这意味着变量在声明时通常需要指定类型,或者 Dart 会通过类型推断自动确定类型。Dart 支持以下几种内置数据类型:
Number (数值): Dart 中的数值类型分为两种:
int: 整数,不带小数点的数字,最大值取决于平台(通常是 64 位)。double: 浮点数,带小数点的数字,符合 IEEE 754 标准。num 类型是 int 和 double 的父类。String (字符串): 表示文本序列。Dart 字符串是 UTF-16 编码的字符序列。可以使用单引号或双引号创建字符串。多行字符串可以使用三引号 ''' 或 """。
Boolean (布尔值): 表示真或假。只有两个值:true 和 false。Dart 是一种类型安全的语言,不允许使用 1 或 0 来表示布尔值。
List (列表): 有序的、可索引的元素集合,类似于其他语言中的数组。Dart 中的 List 是一个泛型类型,可以指定列表中元素的类型。
Set (集合): 无序的、唯一的元素集合。Set 中的元素不能重复。
Map (映射): 键值对的集合,类似于其他语言中的字典或哈希表。Map 中的键是唯一的,值可以重复。
Runes: 用于表示 Unicode 字符序列。通常在处理表情符号或其他特殊字符时使用。
Symbols: 表示在 Dart 程序中声明的运算符或标识符。通常用于反射。
变量声明:
可以使用 var 关键字声明变量,Dart 会自动推断其类型。如果明确知道变量的类型,也可以直接指定类型。
var name = 'Bob'; // 类型推断为 String
String city = 'New York'; // 明确指定类型为 String
int age = 30; // 明确指定类型为 int
double price = 19.99; // 明确指定类型为 double
bool isActive = true; // 明确指定类型为 bool
// 声明一个 List
List<String> fruits = ['apple', 'banana', 'orange'];
// 声明一个 Set
Set<int> uniqueNumbers = {1, 2, 3, 1}; // 实际存储为 {1, 2, 3}
// 声明一个 Map
Map<String, String> capitals = {
'USA': 'Washington D.C.',
'Japan': 'Tokyo'
};
final 和 const 关键字:
final: 用于声明只能赋值一次的变量。final 变量在第一次使用时初始化。const: 用于声明编译时常量。const 变量在编译时就必须确定其值。final String message = 'Hello'; // 运行时常量
const double PI = 3.14159; // 编译时常量
// const 也可以用于构造函数,创建编译时常量对象
const Point origin = Point(0, 0);
在 Flutter 开发中,变量和数据类型无处不在,它们是构建 UI 和处理业务逻辑的基础。理解 Dart 的数据类型对于高效地使用 Flutter 至关重要。
案例:用户注册表单中的数据处理
假设我们正在开发一个用户注册表单,需要收集用户的姓名、年龄、邮箱和密码。这些信息将以不同的数据类型存储。
import 'package:flutter/material.dart';
class RegisterForm extends StatefulWidget {
const RegisterForm({super.key});
@override
State<RegisterForm> createState() => _RegisterFormState();
}
class _RegisterFormState extends State<RegisterForm> {
// 使用 late 关键字延迟初始化,或者在声明时赋初始值
late String _name; // 存储用户姓名,String 类型
late int _age; // 存储用户年龄,int 类型
late String _email; // 存储用户邮箱,String 类型
late String _password; // 存储用户密码,String 类型
bool _agreeToTerms = false; // 存储用户是否同意条款,bool 类型
final TextEditingController _nameController = TextEditingController();
final TextEditingController _ageController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
@override
void dispose() {
_nameController.dispose();
_ageController.dispose();
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
void _submitForm() {
setState(() {
_name = _nameController.text;
_age = int.tryParse(_ageController.text) ?? 0; // 尝试解析为 int,失败则为 0
_email = _emailController.text;
_password = _passwordController.text;
});
// 打印收集到的数据
print('Name: $_name');
print('Age: $_age');
print('Email: $_email');
print('Password: $_password');
print('Agree to terms: $_agreeToTerms');
// 可以在这里进行数据验证或发送到后端
if (_agreeToTerms) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('注册成功!')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('请同意用户条款!')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('用户注册'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: '姓名'),
keyboardType: TextInputType.name,
),
TextField(
controller: _ageController,
decoration: const InputDecoration(labelText: '年龄'),
keyboardType: TextInputType.number,
),
TextField(
controller: _emailController,
decoration: const InputDecoration(labelText: '邮箱'),
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: _passwordController,
decoration: const InputDecoration(labelText: '密码'),
obscureText: true,
),
Row(
children: <Widget>[
Checkbox(
value: _agreeToTerms,
onChanged: (bool? newValue) {
setState(() {
_agreeToTerms = newValue ?? false;
});
},
),
const Text('我同意用户条款'),
],
),
ElevatedButton(
onPressed: _submitForm,
child: const Text('注册'),
),
],
),
),
);
}
}
void main() {
runApp(const MaterialApp(home: RegisterForm()));
}
案例分析:
late String _name;: 这里使用了 late 关键字,表示 _name 变量会在使用前被初始化。在 Flutter 的 StatefulWidget 中,通常会在 initState 或通过 TextEditingController 等方式在 build 方法中获取值。int.tryParse(_ageController.text) ?? 0;: 这是一个将字符串转换为整数的例子。tryParse 方法会尝试将字符串解析为整数,如果解析失败则返回 null。?? 是 Dart 的空值合并运算符,如果 tryParse 返回 null,则使用 0 作为默认值,这体现了 Dart 的空安全特性。bool _agreeToTerms = false;: 布尔类型变量用于存储用户是否同意条款的状态。TextEditingController: Flutter 中用于控制 TextField 文本内容的控制器。final 关键字用于声明这些控制器,因为它们在创建后不会再被重新赋值。List<Widget>: 在 Column 和 Row 中,children 属性接受一个 List<Widget>,这展示了 Dart 中 List 类型在构建 UI 布局时的应用。这个案例展示了如何在 Flutter 应用中声明和使用不同数据类型的变量,以及如何处理用户输入并进行类型转换。理解这些基本概念是构建任何 Flutter 应用的基础。