dart语言教学

Dart 语言教程 ------ 写给前端开发者

本教程面向有 JavaScript / TypeScript 基础的前端工程师,全程用你熟悉的概念做类比。

Dart 是 Flutter 的编程语言,学会 Dart 就掌握了写 Flutter 的一半基础。


目录

  1. [Dart 是什么?和 JS 的关系](#Dart 是什么?和 JS 的关系)
  2. [Hello World 与运行方式](#Hello World 与运行方式)
  3. 变量与类型系统
  4. 内置类型
  5. 函数
  6. 控制流
  7. [集合:List / Map / Set](#集合:List / Map / Set)
  8. [空安全(Null Safety)](#空安全(Null Safety))
  9. 类与面向对象
  10. 继承、抽象类、接口、Mixins
  11. 泛型
  12. [异步编程:Future / Stream / async-await](#异步编程:Future / Stream / async-await)
  13. [Dart 3 新特性:Records 与模式匹配](#Dart 3 新特性:Records 与模式匹配)
  14. 其他常用语法糖
  15. [包管理 pub(对比 npm)](#包管理 pub(对比 npm))
  16. 前端概念对照速查表
  17. 动手练习

1. Dart 是什么?和 JS 的关系

JavaScript / TypeScript Dart
类型系统 TS 是 JS 的超集,编译时擦除 强类型,类型检查贯穿始终
运行方式 解释执行 / JIT 开发时 JIT(热重载快),发布时 AOT 编译成机器码
包管理 npm / yarn / pnpm pub
包仓库 npmjs.com pub.dev
配置文件 package.json pubspec.yaml
编译目标 浏览器 / Node 原生 App(Flutter)、Web、服务端
异步模型 Promise / async-await Future / Stream / async-await
this 动态绑定,坑多 无独立 this 绑定问题,类成员直接引用

核心心法:把 Dart 当成"更像 Java 的 TypeScript"。 你会 TS,Dart 上手只需几天。


2. Hello World 与运行方式

dart 复制代码
// main 是程序入口,类似 JS 里的入口文件
void main() {
  print('Hello, Dart!');
}

运行方式(就像 node xxx.js):

bash 复制代码
dart run bin/main.dart   # 运行脚本
dart format .            # 格式化(类似 prettier)
dart analyze .           # 静态检查(类似 eslint + tsc)

在 Flutter 项目中,入口也是 lib/main.dart 里的 main() 函数。


3. 变量与类型系统(对比 TypeScript)

dart 复制代码
void main() {
  // var ------ 类型推断,和 TS 的 let + 类型推断一样
  var name = 'xiaoming';      // 推断为 String,之后不能赋其他类型
  // name = 123;              // ❌ 编译报错

  // 显式类型声明
  String city = 'Shanghai';
  int age = 25;
  double price = 9.99;

  // final ------ 运行时常量(类似 JS 的 const,赋值后不可变)
  final now = DateTime.now();

  // const ------ 编译期常量,必须在写代码时就能确定值
  const pi = 3.14159;
  const list = [1, 2, 3];

  // dynamic ------ 关闭类型检查(类似 TS 的 any),尽量别用
  dynamic anything = 'hello';
  anything = 42;
}

final vs const(重点,JS 没有 const 的细分)

JS Dart
运行时确定、不可重新赋值 const x = f() final x = f();
编译期就确定 const x = 1 const x = 1;
dart 复制代码
final t = DateTime.now();  // ✅ 运行时求值
// const t2 = DateTime.now(); // ❌ 编译期无法确定

变量声明对照表

TypeScript Dart 说明
let x: number = 1 int x = 1 Dart 数字不分 int/float 变量名
let x = 1 var x = 1 类型推断
const x = 1 final x = 1 运行时常量
const x = 1(字面量) const x = 1 编译期常量
any dynamic 尽量避免
unknown Object? 任意类型但需检查后使用

注意:Dart 没有 let。顶层和类成员可以省略 var,局部变量必须有 var/类型/final 之一。


4. 内置类型

数字:只有 int 和 double

dart 复制代码
int a = 42;
double b = 3.14;
num c = 10;        // num 是 int 和 double 的父类型,类似联合类型 number
c = 3.14;          // ✅ 可以再赋 double

// Dart 3.13 支持:数字用 _ 分隔(大数可读性)
int million = 1_000_000;

字符串:支持插值和三引号

dart 复制代码
var name = 'Dart';

// 单引号双引号等价,和 JS 一样
var s1 = 'hello';
var s2 = "hello";

// 字符串插值:$变量 或 ${表达式}(类似 JS 模板字符串)
var greeting = 'Hello, $name!';           // Hello, Dart!
var sum = '1 + 2 = ${1 + 2}';             // 1 + 2 = 3
var prop = 'len = ${name.length}';        // len = 4

// 多行字符串(类似 JS 的 `` 换行)
var multi = '''
这是第一行
这是第二行
''';

// 原始字符串,不转义(类似 r'' 正则)
var path = r'C:\Users\test';   // \ 不转义

布尔

dart 复制代码
bool ok = true;

// ⚠️ 重要差异:Dart 不会隐式转换真值!
var name = '';
// if (name) { ... }        // ❌ 编译错误!
if (name.isEmpty) { ... }   // ✅ 必须显式判断
if (value != null) { ... }  // ✅ 判空要显式

这是 JS 转 Dart 最容易踩的坑 :0、''、null 在 JS 里都是 falsy,但在 Dart 里只有 bool 类型的 false 才是假,其他类型根本不能用在 if 里。


5. 函数

Dart 函数是一等公民,和 JS 一样。但参数系统更强。

dart 复制代码
// 普通函数,返回类型写在前面
int add(int a, int b) {
  return a + b;
}

// 箭头函数(类似 JS,但函数体只能是单个表达式)
int add2(int a, int b) => a + b;

void main() {
  // 匿名函数 / lambda
  var list = [1, 2, 3];
  list.forEach((item) {
    print(item);
  });
  list.map((n) => n * 2).toList();  // 类似 JS 的 map
}

参数:可选参数、命名参数(和 JS 差异较大,重点!)

dart 复制代码
// 1. 位置可选参数:用 [] 包裹,可传可不传
String greet1(String name, [String? title]) {
  return '${title ?? ''}$name';
}
greet1('Tom');            // Tom
greet1('Tom', 'Mr. ');    // Mr. Tom

// 2. 命名参数:用 {} 包裹,调用时必须写参数名(类似 JS 对象解构传参,但是语法级的)
void createUser({
  required String name,        // required = 必填
  int age = 18,                // 有默认值
  String? email,               // 可空类型
}) {
  print('$name, $age, $email');
}

createUser(name: 'Tom', age: 20);           // ✅
createUser(email: 'a@b.com', name: 'Jerry'); // ✅ 顺序随意
// createUser('Tom');                        // ❌ 必须写 name:
JS Dart
function f(a, b = 1) {} void f(int a, [int b = 1]) {} 位置可选
function f({a, b}) {} + 解构调用 void f({required int a, int? b}) {} 命名参数
默认值 b = 1 一样,int b = 1
无 required 标记 required 关键字强制必填

Flutter 里到处都是命名参数 ,比如 Text('hi', style: TextStyle(fontSize: 16)),先适应这种风格。

函数作为参数和返回值

dart 复制代码
// 函数类型可以显式声明(类似 TS 的类型标注)
int Function(int, int) operation = add;

Function makeCounter() {
  var count = 0;
  return () => ++count;   // 闭包,和 JS 完全一样
}

6. 控制流

大部分和 JS 一致,只讲差异。

dart 复制代码
// if / else:条件必须是 bool(见第 4 节)
// for 循环:和 JS 一致
for (var i = 0; i < 3; i++) { ... }
for (var item in list) { ... }   // 类似 for...of

// switch:Dart 3 的 switch 大升级,支持模式匹配和表达式
String describe(Object obj) {
  return switch (obj) {
    1 => 'one',
    2 || 3 => 'two or three',       // 多值匹配
    int n when n > 10 => 'big int', // 条件匹配(when 守卫)
    String s => 'string: $s',
    _ => 'unknown',                 // _ 相当于 default
  };
}

// while / do-while:和 JS 一致
// break / continue:和 JS 一致

7. 集合:List / Map / Set

JS Dart
Array List
Object(当字典用) / Map Map
Set Set
dart 复制代码
// List ------ 类似 JS 数组
var list = [1, 2, 3];
list.add(4);              // push
list.removeAt(0);         // shift
list.length;              // 长度
list[0];                  // 索引访问
list.indexOf(2);          // 同 JS
list.where((n) => n > 1).toList();   // filter(注意 where 返回的是惰性 Iterable,要 toList())
list.map((n) => n * 2).toList();     // map
list.reduce((a, b) => a + b);        // reduce
list.any((n) => n > 2);              // some
list.every((n) => n > 0);            // every
list.first; list.last; list.isEmpty; list.isNotEmpty;

// 展开运算符和 null 感知展开(Flutter 布局里天天用)
var a = [1, 2];
var b = [0, ...a];          // [0, 1, 2]
List<int>? maybe;
var c = [0, ...?maybe];     // maybe 为 null 时不报错

// 集合 if / for(Flutter 布局利器)
var showAll = true;
var widgets = [
  'header',
  if (showAll) 'body',      // 条件加入元素
  for (var i = 0; i < 3; i++) 'item$i',  // 循环生成元素
];

// Map ------ 类似 JS 对象/Map
var map = {'name': 'Tom', 'age': 18};
map['name'];             // 访问
map['email'] = 'a@b.c';  // 添加/修改
map.containsKey('name');
map.keys; map.values;
map.forEach((k, v) => print('$k: $v'));

// Set
var set = {1, 2, 3};
set.add(3);          // 重复元素自动去重

⚠️ JS 里 Array.isArray / typeof 的习惯要改:Dart 用 is 关键字判断类型,如 if (obj is List)。


8. 空安全(Null Safety)------最重要

Dart 3 默认开启空安全,规则和 TS 的 strictNullChecks 一样:null 是独立的类型,不能赋给非空类型。

dart 复制代码
String a = 'hello';
// a = null;          // ❌ 编译错误

String? b = null;     // String? 表示可空(同 TS 的 string | null)
b = 'world';

// ── 处理可空值的各种姿势 ──

// 1. 安全调用 ?. (同 JS)
print(b?.length);     // b 为 null 时返回 null,不报错

// 2. 空值合并 ?? (同 JS 的 ??)
var len = b?.length ?? 0;   // b 为 null 时取 0

// 3. 断言 ! (同 TS 的 !,如果实际是 null 会抛异常,谨慎使用)
var force = b!.length;

// 4. if 判空后,类型自动提升(和 TS 一样的类型收窄)
if (b != null) {
  print(b.length);    // ✅ 这里 b 被"提升"为 String,不用 ?
}

// 5. 局部变量提升的限制:类成员属性不会提升!
class User {
  String? name;
  void show() {
    // if (name != null) { print(name.length); } // ❌ name 是成员属性,Dart 无法保证中途没被改
    if (name != null) {
      final n = name!;          // 方案1:!
      print(n.length);
    }
    final n2 = name;            // 方案2:先赋给局部变量(推荐)
    if (n2 != null) print(n2.length);
  }
}

// 6. late ------ "稍后初始化"的非空变量(Flutter 状态管理常用)
late String token;
void init() {
  token = 'abc';   // 使用前必须先赋值,否则抛异常
}
场景 TypeScript Dart
可空类型 `string null`
安全访问 a?.b a?.b
默认值 a ?? b a ?? b
非空断言 a! a!
类型收窄 if (a !== null) if (a != null)(仅局部变量/参数)

9. 类与面向对象

Dart 的 class 比 ES6 class 更强(更像 TS + Java),所有成员默认都有隐式 getter/setter。

dart 复制代码
class User {
  // 实例字段(必须给类型或 final/var)
  String name;
  int age;

  // 静态字段(同 JS static)
  static const maxAge = 150;

  // 构造函数:Dart 的经典写法是"参数直接赋给字段"的语法糖
  // 等价于 JS 里:constructor(name, age) { this.name = name; this.age = age; }
  User(this.name, this.age);

  // 命名构造函数 ------ Dart 没有 JS 的函数重载,用命名构造函数代替!
  User.guest() : name = 'Guest', age = 0;

  // 从 Map 创建(后端返回 JSON 时常用)
  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        age = json['age'];

  // 方法
  void greet() {
    print('Hi, I am $name');   // 类内直接用字段名,不需要 this(Flutter 官方 lint 甚至禁止多余的 this)
  }

  // getter / setter
  String get intro => '$name ($age)';   // 计算属性,像 TS 的 get
  set nick(String n) => name = n;

  // toString
  @override
  String toString() => 'User($name, $age)';
}

void main() {
  var u = User('Tom', 18);
  var g = User.guest();          // 调用命名构造函数
  var j = User.fromJson({'name': 'Jerry', 'age': 20});
  print(u.intro);                // Tom (18)
  u.nick = 'TOMMY';
}

构造函数进阶

dart 复制代码
class Point {
  final double x, y;

  // 1. 命名参数构造函数 ------ Flutter 里最常见的写法
  Point({required this.x, required this.y});

  // 2. 可选:加默认值
  // Point({this.x = 0, this.y = 0});

  // 3. 重定向构造函数
  Point.origin() : this(0, 0);

  // 4. 常量构造函数(所有字段 final 时可用,Flutter 里大量使用)
  const Point.zero() : x = 0, y = 0;
}

// const 构造函数配合 const 变量:编译期常量,Flutter 性能优化常用
const p = Point.zero();

// 5. 工厂构造函数 factory ------ 可以返回缓存/子类实例,不一定创建新对象
class Logger {
  static final Logger _instance = Logger._internal();
  Logger._internal();                    // 私有构造函数(_ 开头 = 库内私有)
  factory Logger() => _instance;         // 单例模式
}

私有化:Dart 没有真正的 private,用 _ 前缀

dart 复制代码
// Dart 的隐私是"库级别"的:同一个 .dart 文件内的代码都能互相访问
class Secret {
  String _hidden = 'private';   // _ 开头 = 对其他文件不可见
  String visible = 'public';
}

前端类比:_ 前缀 ≈ 约定俗成的 _private,但 Dart 有编译器强制(跨文件不可见)。同一项目里看到大量 _ 开头的类/变量/文件,都表示"仅内部使用"。


10. 继承、抽象类、接口、Mixins

dart 复制代码
// ── 继承 extends(同 JS)──
class Animal {
  void eat() => print('eating');
}

class Dog extends Animal {
  @override                       // 重写必须加 @override 注解(lint 强制)
  void eat() {
    super.eat();                  // 同 JS 的 super
    print('dog eating');
  }
}

// ── 抽象类 abstract(TS 也有)──
abstract class Shape {
  double get area;                // 抽象成员,子类必须实现
  void draw();
}

class Circle extends Shape {
  @override
  double get area => 3.14;
  @override
  void draw() => print('draw circle');
}

// ── 接口:Dart 没有 interface 关键字!──
// 每个类都隐式是一个接口,用 implements 实现"接口"
class Fake implements Shape {
  @override
  double get area => 0;   // implements 要求实现所有成员(包括已有的具体实现)
  @override
  void draw() {}
}

// ── Mixin:多重继承的解决方案(TS 没有的重要特性,Flutter 里极其常用)──
mixin Flyer {
  void fly() => print('flying');
}

mixin Swimmer {
  void swim() => print('swimming');
}

class Duck extends Animal with Flyer, Swimmer {}   // with 关键字混入

// mixin 也可以限制只能被某些类型使用
mixin Walk on Animal {          // on Animal:只能混入 Animal 及其子类
  void walk() => print('walking');
}

一句话总结:extends 继承一个类,with 混入多个 mixin,implements 实现接口(要求重写所有成员)。

Flutter 里的例子:class _MyHomePageState extends State<MyHomePage>,很多组件会 with SingleTickerProviderStateMixin。


11. 泛型

和 TS 泛型几乎一样。

dart 复制代码
// 泛型函数
T first<T>(List<T> items) => items[0];

// 泛型类
class Box<T> {
  T value;
  Box(this.value);
}

// 泛型约束(类似 TS 的 extends 约束)
T max<T extends num>(T a, T b) => a > b ? a : b;

// 使用
var box = Box<int>(42);
var n = max(3, 5);        // 类型自动推断

12. 异步编程:Future / Stream / async-await

好消息:async/await 语法和 JS 完全一样。区别在于类型名。

JS Dart 说明
Promise<T> Future<T> 表示"将来会有一个值"
--- Stream<T> 表示"将来会有多个值"(类似事件流/RxJS Observable)
async/await async/await 一模一样
Promise.all Future.wait 并发等待多个
try/catch + await 一样 错误处理一致
dart 复制代码
// Future 基础
Future<String> fetchUser() async {
  await Future.delayed(Duration(seconds: 1));  // 类似 sleep,模拟网络请求
  return 'Tom';
}

void main() async {
  var user = await fetchUser();     // 同 JS await
  print(user);
}

// Future 的链式调用(类似 .then,不推荐,用 await 更清晰)
fetchUser().then((u) => print(u)).catchError((e) => print(e));

// 并发请求(类似 Promise.all)
var results = await Future.wait([fetchUser(), fetchUser()]);

// 错误处理(同 JS)
try {
  await fetchUser();
} catch (e) {
  print('error: $e');
} finally {
  print('done');
}

// Stream:多个异步值(JS 没有直接对应物,可理解为内置的 Observable)
Stream<int> countStream() async* {   // async* 生成器函数
  for (var i = 0; i < 3; i++) {
    yield i;                          // 类似 RxJS 的 next
    await Future.delayed(Duration(seconds: 1));
  }
}

void listen() async {
  await for (var n in countStream()) {   // await for:逐个消费
    print(n);
  }
  // 或者
  // countStream().listen((n) => print(n));
}

单线程事件循环 :Dart 和 JS 一样是单线程事件循环模型,Future 微任务/事件队列的调度思想和 JS 的宏任务/微任务非常接近,你的异步直觉可以直接复用。


13. Dart 3 新特性:Records 与模式匹配

(Dart 3 以后才有,本项目 SDK 3.13 支持)

Records:轻量元组(JS 没有对应物,TS 的 tuple 类型)

dart 复制代码
// 返回多个值,不用定义类了
(String, int) getUserInfo() {
  return ('Tom', 18);
}

void main() {
  var (name, age) = getUserInfo();     // 解构
  print('$name is $age');

  // 具名字段
  ({String name, int age}) user = (name: 'Jerry', age: 20);
  print(user.name);
}

模式匹配:解构 + 匹配

dart 复制代码
// switch 表达式 + 解构
var json = {'name': 'Tom', 'age': 18};

switch (json) {
  case {'name': String n, 'age': int a}:
    print('$n $a');
  default:
    print('unknown');
}

// 列表模式
var list = [1, 2, 3];
var [first, second, ...rest] = list;   // 类似 JS 数组解构

// 对象模式
if (user case User(name: var n, age: >= 18)) {   // 匹配 + 条件
  print('adult: $n');
}

14. 其他常用语法糖

dart 复制代码
// ── 级联操作符 .. :对同一对象连续操作(JS 没有)──
var btn = Button()
  ..text = 'Click'
  ..width = 100
  ..onClick = () => print('clicked');
// 等价于 btn.text = ...; btn.width = ...; 每次都返回对象本身

// ── 条件成员访问与赋值 ──
map['count'] ??= 0;        // 为 null 才赋值

// ── 三元运算符:同 JS ──
var msg = age >= 18 ? 'adult' : 'minor';

// ── 类型判断与转换 ──
if (obj is String) { ... }         // 类似 typeof/instanceof,类型收窄
if (obj is! String) { ... }        // 非
var s = obj as String;             // 强制转换,类似 <string>obj

// ── 注解 ──
@override      // 重写父类成员
@deprecated    // 标记弃用

常用工具方法

dart 复制代码
// DateTime
var now = DateTime.now();
var later = now.add(Duration(days: 1));
now.isBefore(later);      // true
now.difference(later).inHours;

// Duration(时间长度)
Duration(seconds: 90);

// 字符串
'tom'.toUpperCase();
' a b '.trim();
'a,b,c'.split(',');
var joined = [1, 2].join('-');   // '1-2'
'int'.padLeft(5);                // '  int'

// num
var x = 3.7;
x.round();   // 4
x.floor();   // 3
3.toString();        // '3'
int.parse('42');     // 42
double.tryParse('abc');  // null(不抛异常的 parse 系列)

15. 包管理 pub(对比 npm)

yaml 复制代码
# pubspec.yaml ------ 相当于 package.json
name: flutter_application_1
environment:
  sdk: ^3.13.5            # Dart 版本约束(同 npm 的 engines)

dependencies:              # 类似 dependencies
  http: ^1.2.0            # ^ 同 npm 语义:允许小版本更新
  cupertino_icons: ^1.0.8

dev_dependencies:          # 类似 devDependencies
  flutter_test:
    sdk: flutter
  flutter_lints: ^6.0.0
npm 命令 pub 命令
npm install flutter pub get(或 dart pub get)
npm install <pkg> 在 pubspec.yaml 添加依赖后 pub get
npm update flutter pub upgrade
npm outdated flutter pub outdated
npx <cmd> dart run <pkg>:<cmd> 或 flutter pub run
package.json pubspec.yaml
node_modules 无全局缓存目录(.dart_tool 存配置)
npmjs.com pub.dev
lock 文件 package-lock.json pubspec.lock
eslint flutter_lints(在 analysis_options.yaml 配置)

16. 前端概念对照速查表

你熟悉的 Dart / Flutter 对应
let / var var(局部)/ 直接写字段
const(对象) final
const(字面量) const
=== ==(Dart 没有三等号,== 默认就是严格比较;类可重写 ==)
typeof / instanceof is
类型断言 as
`string null`
Array List
对象当字典 Map
模板字符串 ${x} 插值 '$x' / '${x.y}'
Promise Future
async/await async/await(一模一样)
RxJS Observable Stream
Promise.all Future.wait
npm pub
package.json pubspec.yaml
class 私有字段 #x _x(库级私有)
构造函数重载 命名构造函数 Class.name()
mixin(TS 的 implements 混合) mixin + with(一等公民支持)
解构赋值 记录解构 / 模式匹配
真值判断陷阱 if 条件必须是 bool,改掉 JS 习惯

17. 动手练习

把下面的代码保存为 bin/practice.dart,用 dart run 运行验证学习成果:

dart 复制代码
// 练习:实现一个简单的用户管理系统
// 要求:
// 1. 定义 User 类,包含 name(必填)、age(默认 18)、tags(可选列表)
// 2. 提供命名构造函数 User.fromJson
// 3. 提供 getter:isAdult
// 4. 写一个函数 findAdults(List<User>) 返回所有成年人
// 5. 用 async/await 模拟异步加载用户列表并打印

class User {
  final String name;
  final int age;
  final List<String> tags;

  User({required this.name, this.age = 18, this.tags = const []});

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        age = json['age'] ?? 18,
        tags = List<String>.from(json['tags'] ?? []);

  bool get isAdult => age >= 18;

  @override
  String toString() => 'User($name, $age)';
}

List<User> findAdults(List<User> users) =>
    users.where((u) => u.isAdult).toList();

Future<List<User>> loadUsers() async {
  await Future.delayed(const Duration(seconds: 1));
  return [
    User(name: 'Tom', age: 20, tags: ['admin']),
    User.fromJson({'name': 'Jerry', 'age': 16}),
    User.fromJson({'name': 'Spike'}),
  ];
}

void main() async {
  final users = await loadUsers();
  print('全部用户: $users');
  print('成年人: ${findAdults(users)}');
}

下一步

学完本教程后,建议继续学习:

  • Flutter 基础:Widget、State、BuildContext、布局系统(Row/Column/Stack)
  • 状态管理:setState → Provider → Riverpod/BLoC
  • 官方文档:https://dart.dev/language (语言之旅,交互式示例)

本教程基于 Dart 3.x(SDK ^3.13.5)编写,与项目 pubspec.yaml 环境一致。

相关推荐
光影少年1 小时前
如果 React 组件的属性没有传值,它的默认值是什么?
前端·javascript·react.js
风骏时光牛马1 小时前
AI_Coding:智能代码生成与工程实践
前端
颜进强1 小时前
22 · NestJs InjectionScopes 注入作用域:默认单例不是偷懒,是最优——以及何时才该打破
前端·后端·ai编程
liangshanbo12152 小时前
Web Worker 在 AI 前端应用中有什么具体使用场景?
前端·人工智能
拖孩2 小时前
一个全程 AI 写的小程序「厨菜记」,上线 20 天跑通流量主,收入几块钱,开心得不行
前端·后端·微信小程序
颜进强2 小时前
21 · NestJs AsyncProviders 异步提供者:useFactory 返回 Promise 之后,容器发生了什么
前端·后端·ai编程
莪_幻尘2 小时前
Agent 体检:乱编、连锁、失忆,给 Agent 做一次五维体检
前端·人工智能·agent
秋天的一阵风2 小时前
🚀 nacos-web-config:运营半夜改条配置,网页秒更新 —— 不用发版、不用轮询,我把它开源了
java·前端·开源
不一样的少年_3 小时前
别用前端思维写后端:一张 5MB 图片,为什么能撑爆内存?
前端·后端·图片资源