Flutter中的Future和Stream
在 Flutter 中,Future
和 Stream
都是用于处理异步操作的类,它们都基于 Dart 的异步编程模型,但是它们的使用场景和工作方式有所不同。以下是它们的区别以及各自适用的场景。
目录
- 一、Future
- 1、基本使用
- 2、异常处理
- 1. catchError
- 2. onError
- 3、`catchError` 和 `onError` 的区别
- 4. 捕获多个错误
- 5. 错误的传播
- 总结
- 二、Stream
- 1、基本使用
- 2、异常处理
- 1. `onError` 处理器
- 2. `try-catch` 语句
- 3. 异常后流的状态
- 4. 流的中断
- 5. 恢复流
- 6. 流异常的示例
- 总结
- 三、 结合使用 `Future` 和 `Stream`
- 四、总结
- 1、区别
- 2、选择 `Future` 还是 `Stream`
- 四、疑问
- 1、Stream 流是按照顺序执行的吗?
- 1. 顺序性
- 2. 顺序的保证
- 2、Stream async* 和 yield 的解释这三个必须要配套使用吗?,不适用 yield 行吗?
- 1. `Stream` 与 `async*`
- 2. `async*` 和 `yield` 必须配合使用吗?
- 3. 不使用 `yield` 行不行?
- 4. 如何使用 `async*` 生成异步数据流?
- 总结
一、Future
1、基本使用
Future
是一个表示一个可能还未完成的异步操作的对象。它表示一个将来某个时间点会返回一个结果或错误的计算。
- 特点:
Future
代表的是一个 单次 异步操作。- 只能返回一次结果或错误,不会再有后续的值。
- 在调用时,它会返回一个
Future
对象,可以通过then
或await
等方法获取结果。 - 如果操作失败,可以通过
catchError
或onError
进行错误处理。
- 使用场景:
- 当你需要等待一个单一的异步结果时,使用
Future
。 - 比如从网络获取数据,执行一个数据库查询,或读取一个文件等一次性的操作。
- 当你需要等待一个单一的异步结果时,使用
- 示例代码:
// 使用 Future 的示例
Future<String> fetchData() async {// 模拟异步操作await Future.delayed(Duration(seconds: 2));return "Data fetched successfully!";
}void main() async {try {String data = await fetchData();print(data); // 输出 "Data fetched successfully!"} catch (e) {print("Error: $e");}
}
在上面的示例中,fetchData
返回一个 Future<String>
,它表示一个将来完成的异步操作。使用 await
来等待这个操作完成并获得结果。
2、异常处理
1. catchError
catchError
是用于捕获和处理 Future
发生错误的一种方式。当 Future
执行失败时,它会触发传给 catchError
的回调函数。这个回调函数可以接受错误和栈跟踪信息。
示例:
Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;});
}void main() {divide(10, 0).catchError((e) {print('Error: $e');});// Output: Error: Exception: Cannot divide by zero!
}
在这个例子中,当 b
为 0 时,Future
会抛出一个 Exception
,并且 catchError
捕获并打印这个错误。
catchError
的用法细节:
- 返回值的传递:
catchError
会继续执行Future
链中的后续操作,因此如果你想在错误发生时返回一个默认值,可以在catchError
中指定。
Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;}).catchError((e) {print('Handled error: $e');return -1; // 返回默认值});
}void main() async {var result = await divide(10, 0);print('Result: $result'); // 输出: Handled error: Exception: Cannot divide by zero!// Result: -1
}
2. onError
onError
是 Future
的另一种错误处理方式。它与 catchError
类似,但它是 Future
构造函数的一部分,通常用于直接在 Future
构造时附加错误处理。
示例:
Future<int> divide(int a, int b) {return Future.delayed(Duration(seconds: 1), () {if (b == 0) {throw Exception('Cannot divide by zero!');}return a ~/ b;}).onError((error, stackTrace) {print('Caught an error: $error');return -1; // 返回默认值});
}void main() async {var result = await divide(10, 0);print('Result: $result'); // 输出: Caught an error: Exception: Cannot divide by zero!// Result: -1
}
3、catchError
和 onError
的区别
catchError
是用于捕获在Future
执行时抛出的异常,它通常用于链式调用中捕获错误。onError
是Future
的一种附加错误处理机制,它将错误处理直接嵌入到Future
构造中。
尽管 catchError
和 onError
都可以捕获错误并返回一个默认值或执行某些操作,但 catchError
更灵活,通常在复杂的异步链式操作中使用。
4. 捕获多个错误
如果你需要捕获多个错误,可以将 catchError
或 onError
绑定到多个 Future
链条上。这样可以对不同类型的错误进行不同的处理。
示例:
Future<void> asyncFunction() {return Future.delayed(Duration(seconds: 1), () {throw Exception('Something went wrong!');});
}void main() {asyncFunction().catchError((e) {print('Caught error: $e');}).catchError((e) {print('Another handler for errors: $e');});// Output: Caught error: Exception: Something went wrong!
}
5. 错误的传播
如果在 Future
中没有处理错误,错误将会被传播,直到被外部捕获或程序崩溃。因此,适当的错误处理不仅可以帮助捕获问题,还可以避免未捕获的异常导致程序崩溃。
总结
在 Dart 中,catchError
和 onError
都可以用于处理异步操作中的错误。它们的主要区别在于用法和灵活性,选择哪一个取决于你的代码结构和需求。
二、Stream
1、基本使用
Stream
是一个表示一系列异步事件的对象,它允许你在未来的时间点接收多个值。
- 特点:
Stream
代表的是 多个异步事件。- 它会按顺序提供一系列的结果(可以是零个或多个),通常用于处理实时数据流。
- 可以是单向的,也可以是广播流(多个监听者可以订阅)。
- 你可以通过
listen
方法来监听事件流。 Stream
还支持await for
语法,可以等待并处理每个事件。
- 使用场景:
- 当你需要处理一个 数据流 或 多个值 时,使用
Stream
。 - 比如处理实时数据(如 WebSocket 数据流、用户输入事件流、文件变化等)。
- 当你需要处理一个 数据流 或 多个值 时,使用
- 示例代码:
// 使用 Stream 的示例
Stream<int> generateNumbers() async* {for (int i = 0; i < 5; i++) {await Future.delayed(Duration(seconds: 1));yield i; // 每秒产生一个数字}
}void main() async {await for (var number in generateNumbers()) {print(number); // 输出:0, 1, 2, 3, 4}
}
在这个示例中,generateNumbers
返回一个 Stream<int>
,它每秒返回一个整数。通过 await for
循环,我们可以逐个接收流中的数据。
2、异常处理
当流中发生异常时,有几种方式来处理这些异常,使得流能够继续工作或适当地终止。
1. onError
处理器
如果你使用 Stream.listen
方法来监听流,可以通过传入 onError
回调来处理流中的异常。当流抛出异常时,onError
处理器会被触发。
Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Something went wrong');yield 3; // 这一行永远不会执行
}void main() {generateNumbersWithError().listen((data) {print('Received: $data');},onError: (error) {print('Caught error: $error');},onDone: () {print('Stream is done');},);
}
输出:
Received: 1
Received: 2
Caught error: Exception: Something went wrong
Stream is done
在这个例子中,当 Stream
中的 Exception
被抛出时,onError
回调会捕获并打印出错误信息。yield 3
后的代码不会执行,因为流在抛出异常后被中断。
2. try-catch
语句
在异步生成器(如 async*
)中,你可以使用 try-catch
来捕获异常,这可以防止异常导致流中断。
Stream<int> generateNumbersWithErrorHandled() async* {try {yield 1;yield 2;throw Exception('Something went wrong');yield 3; // 这一行不会执行} catch (e) {print('Caught error: $e');}
}void main() async {await for (var data in generateNumbersWithErrorHandled()) {print('Received: $data');}
}
输出:
Received: 1
Received: 2
Caught error: Exception: Something went wrong
在这个例子中,即使抛出异常,Stream
仍然能够继续执行,只是异常会被捕获并处理。
3. 异常后流的状态
当 Stream
抛出异常后,流会进入错误状态,并且不再发出任何数据,除非你有合适的机制来恢复流。
- 如果流中的
onError
回调没有捕获异常,流会直接终止。 - 如果你在
Stream
中使用try-catch
捕获了异常,流可以继续正常工作,继续发送后续的数据。
4. 流的中断
流的中断意味着流不再继续发出事件。中断的原因通常有以下几种:
- 异常抛出:如果流中的某个操作抛出了异常,流会被中断,后续的事件不会再触发。
- 用户主动取消订阅:如果你使用
StreamSubscription
来订阅流,并主动调用cancel()
,流也会中断。 - 流结束:如果流完成(即没有更多的事件要发出),流会进入完成状态。
5. 恢复流
如果你希望在流发生异常后恢复流的工作,可以通过重新订阅流或使用一些复合的错误处理机制。
例如,在监听流时使用 onError
捕获错误并在错误发生时重新启动流:
Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Something went wrong');yield 3;
}void main() {Stream<int> stream = generateNumbersWithError();stream.listen((data) {print('Received: $data');},onError: (error) {print('Caught error: $error');// 重新启动流stream.listen((data) => print('Retry received: $data'),onError: (e) => print('Retry error: $e'),onDone: () => print('Retry stream is done'),);},onDone: () => print('Stream is done'),);
}
在这种情况下,流会在错误发生时重新启动。这允许你捕获错误并尝试恢复流的执行。
6. 流异常的示例
假设有一个 Stream
生成器,它在生成某个事件时发生异常:
Stream<int> generateNumbersWithError() async* {yield 1;yield 2;throw Exception('Unexpected error');yield 3; // 这行永远不会执行
}void main() async {try {await for (var number in generateNumbersWithError()) {print('Received: $number');}} catch (e) {print('Caught error: $e');}
}
输出:
Received: 1
Received: 2
Caught error: Exception: Unexpected error
在这个例子中,异常会导致流中断,后续的事件不会被处理,且异常被捕获。
总结
- 流中断:当流遇到异常时,流会进入错误状态并停止发出事件。
- 异常处理:你可以通过
onError
回调或try-catch
语句捕获和处理异常。 - 恢复流:在流发生异常时,可以选择恢复流的工作,例如通过重新订阅流。
三、 结合使用 Future
和 Stream
在某些情况下,Future
和 Stream
可以结合使用。例如,如果你有一个 Future
返回一个数据集,而这个数据集可以被逐步处理,那么你可以将 Future
的结果转换成一个 Stream
来进行逐项处理。
Future<List<int>> fetchData() async {return [1, 2, 3, 4, 5];
}Stream<int> fetchDataAsStream() async* {List<int> data = await fetchData();for (var item in data) {yield item;}
}void main() async {await for (var number in fetchDataAsStream()) {print(number); // 输出 1, 2, 3, 4, 5}
}
在这个例子中,fetchData
是一个 Future
,而 fetchDataAsStream
将其转换成了一个 Stream
,使得我们能够以流的形式逐项处理数据。
总结
Future
适合用于处理 单次 的异步操作,返回一个值或错误。Stream
适合用于处理 多次 的异步事件或数据流,允许你持续接收多个值。
了解它们的区别和使用场景可以帮助你更好地选择异步操作的方式,从而提高代码的可读性和性能。
四、总结
1、区别
特性 | Future | Stream |
---|---|---|
返回值 | 只返回一个值或一个错误 | 持续返回多个值或错误 |
生命周期 | 一次性操作,完成后不再有新的值 | 持续发出多个值(或者是事件) |
异步操作 | 适用于单次异步操作 | 适用于多次异步事件或数据流 |
操作方式 | then 、catchError 、await | listen 、await for 、add 、addError |
2、选择 Future
还是 Stream
- 使用
Future
:- 你在处理一个单次的异步操作时。
- 比如从网络获取数据、计算结果、执行数据库操作等。
- 示例:登录请求、获取单个 API 响应、读取文件内容。
- 使用
Stream
:- 当你需要处理 多个异步事件,例如实时数据流或变化时。
- 比如 WebSocket 消息、实时位置更新、文件读取(大文件分片)等。
- 示例:实时聊天消息、连续的数据更新、传感器数据流等。
四、疑问
1、Stream 流是按照顺序执行的吗?
是的,Stream
在 Dart 中是 按顺序 执行的。具体来说,Stream
中的事件(数据或错误)会按照它们被 产生 或 发出 的顺序进行传递和处理。
1. 顺序性
在 Dart 中,Stream
会按照 事件发出的顺序 将这些事件传递给订阅者。也就是说,先发出的事件会先被监听器处理。
例如,如果你有一个 Stream
生成数据流,并且在每个数据项之间有延时,那么监听器将会按照数据产生的顺序处理每个事件。
示例代码:顺序执行的 Stream
Stream<int> generateNumbers() async* {for (int i = 0; i < 3; i++) {await Future.delayed(Duration(seconds: 1)); // 模拟延时yield i; // 按顺序发出数据}
}void main() async {await for (var number in generateNumbers()) {print('Received: $number'); // 按顺序输出}
}
输出:
Received: 0
Received: 1
Received: 2
在这个例子中,数据流是按顺序传递给监听器的,即 0
、1
、2
按照生成的顺序被逐个输出。
2. 顺序的保证
Stream
本身的设计保证了事件的顺序。无论你是通过 await for
或者 listen
来处理事件,事件会按照发出顺序依次传递给你。
通过 listen
监听的顺序
Stream<int> generateNumbers() async* {for (int i = 0; i < 3; i++) {await Future.delayed(Duration(seconds: 1));yield i;}
}void main() {generateNumbers().listen((data) {print('Received: $data'); // 按顺序输出});
}
这段代码会输出:
Received: 0
Received: 1
Received: 2
如上所示,数据按照顺序传递。
2、Stream async* 和 yield 的解释这三个必须要配套使用吗?,不适用 yield 行吗?
在 Dart 中,Stream
、async*
和 yield
是紧密关联的,但它们不一定是必须同时使用的。它们之间的关系可以分开解释,看看如何组合使用,或者是否可以在没有 yield
的情况下使用 async*
。
1. Stream
与 async*
Stream
是 Dart 中用于处理异步数据流的核心概念。Stream
对象用于处理一系列异步事件,而 async*
是定义异步生成器(异步迭代器)的一种语法。async*
允许你生成一个 Stream
,并通过 yield
来发出数据。
async*
标识一个异步生成器函数,它返回一个Stream
。yield
用于在异步生成器中逐个发出数据。
2. async*
和 yield
必须配合使用吗?
async*
和yield
一般是配套使用的,但你也可以只使用async*
,并没有强制要求一定要用yield
。- 如果你不需要发出数据(即你不想使用
yield
),你也可以用async*
作为一个简单的异步函数来返回一个空的Stream
,或者使用await
来发出异步的结果。
3. 不使用 yield
行不行?
是的,可以在没有 yield
的情况下使用 async*
,但通常这样做的结果是流不会发出任何数据。在这种情况下,Stream
会是一个空的流,或者说它在没有任何数据的情况下完成。
示例 1:不使用 yield
,生成一个空的流
Stream<int> generateEmptyStream() async* {// 什么都不发出
}void main() async {await for (var value in generateEmptyStream()) {print(value); // 这里不会有任何输出}
}
在这个例子中,async*
只是声明了一个异步生成器,但是没有 yield
,因此返回的 Stream
是空的,不会有任何数据输出。
4. 如何使用 async*
生成异步数据流?
async*
用于返回 Stream
,可以通过 yield
来逐个发出数据。你也可以结合 await
来进行异步操作后再发出数据。这是一个典型的用法:
Stream<int> generateNumbers() async* {for (int i = 1; i <= 5; i++) {await Future.delayed(Duration(seconds: 1)); // 模拟异步操作yield i; // 发出数据}
}void main() async {await for (var number in generateNumbers()) {print(number);}
}
输出:
1
2
3
4
5
在这个例子中,async*
通过 yield
发出了多个数字,每次发出时都延迟 1 秒。
总结
async*
和yield
通常一起使用来生成和发出异步数据流。- 不一定非要有
yield
(但不使用 yield 意义不大),但如果你希望生成一个有数据的流,就需要使用yield
或其他发出数据的方式(例如yield*
)。 - 如果你在
async*
中没有yield
,返回的Stream
将不会发出任何数据,通常这种情况用于创建空流或只执行异步操作的函数。
因此,虽然 async*
和 yield
是紧密相关的,但它们不必总是同时使用。如果不使用 yield
,可以生成一个空流或执行异步操作,但不会有数据发出。
相关文章:
Flutter中的Future和Stream
在 Flutter 中,Future 和 Stream 都是用于处理异步操作的类,它们都基于 Dart 的异步编程模型,但是它们的使用场景和工作方式有所不同。以下是它们的区别以及各自适用的场景。 目录 一、Future1、基本使用2、异常处理1. catchError2. onError…...
Python将Excel文件转换为JSON文件
工作过程中,需要从 Excel 文件中读取数据,然后交给 Python 程序处理数据,中间需要把 Excel 文件读取出来转为 json 格式,再进行下一步数据处理。 这里我们使用pandas库,这是一个强大的数据分析工具,能够方便地读取和处理各种数据格式。需要注意的是还需要引入openpyxl库,…...
MySQL中EXPLAIN的介绍、作用、字段含义
MySQL中EXPLAIN的介绍、作用、字段含义 在MySQL中,EXPLAIN 是一个非常有用的命令,它可以帮助开发者和DBA理解查询执行计划,从而优化查询性能。EXPLAIN 可以模拟优化器执行SQL查询语句,而不真正执行这条语句,从而帮助用…...
Socket编程:UDP网络编程项目
目录 一、回显服务器 二、翻译器 三、聊天室 一、回显服务器 项目介绍:使用UDPIPv4协议进行Linux网络编程,实现回显服务器和客户端 功能介绍:客户端发送数据,经过服务端再返回到客户端,输出数据 源代码࿱…...
uniapp echarts tooltip formation 不识别html
需求: echarts 的tooltip 的域名太长,导致超出屏幕 想要让他换行 思路一: 用formation自定义样式实现换行 但是: uniapp 生成微信小程序, echart种的tooltip 的formation 识别不了html ,自定义样式没办…...
从0开始linux(39)——线程(2)线程控制
欢迎来到博主的专栏:从0开始linux 博主ID:代码小豪 文章目录 线程创建线程标识符线程参数多线程竞争资源 回收线程detach 线程退出pthread_cancel 线程创建 线程创建的函数为pthread_create。该函数是包含在posix线程库当中,posix线程是C语言…...
对载入的3dtiles进行旋转、平移和缩放变换。
使用 params: {tx: 129.75845, //模型中心X轴坐标(经度,单位:十进制度)//小左ty: 46.6839, //模型中心Y轴坐标(纬度,单位:十进制度)//小下tz: 28, //模型中心Z轴坐标(高…...
YOLO模型训练后的best.pt和last.pt区别
在选择YOLO模型训练后的权重文件best.pt和last.pt时,主要取决于具体的应用场景:12 best.pt:这个文件保存的是在训练过程中表现最好的模型权重。通常用于推理和部署阶段,因为它包含了在验证集上表现最好的模型权重&#x…...
Qt 项目中同时使用 CMAKE_AUTOUIC 和 UiTools 的注意事项
在 Qt 项目开发中,.ui 文件是界面设计的重要组成部分。开发者可以通过两种主要方式使用 .ui 文件: 编译期处理:通过 Qt 的 uic 工具将 .ui 文件转化为 C 代码(ui_xxx.h),静态绑定到项目中。运行时动态加载…...
不玩PS抠图了,改玩Python抠图
网上找了两个苏轼的印章图片: 把这两个印章抠出来的话,对于不少PS高手来说是相当容易,但是要去掉其中的水印,可能要用仿制图章慢慢描绘,图章的边缘也要慢慢勾画或者用通道抠图之类来处理,而且印章的红色也不…...
ubuntu 22.04 mini 安装,在配置网络时重启后配置文件被重置原因与解决方法
在 /etc/netplan/50-cloud-init.yaml 配置文件中有一段注释中有说明 rootlocalhost:/etc/netplan# cat 50-cloud-init.yaml # This file is generated from information provided by the datasource. Changes # to it will not persist across an instance reboot. To disab…...
【Go底层】time包Ticker定时器原理
目录 1、背景2、go版本3、源码解释【1】Ticker结构【2】NewTicker函数解释 4、代码示例5、总结 1、背景 说到定时器我们一般想到的库是cron,但是对于一些简单的定时任务场景,标准库time包下提供的定时器就足够我们使用,本篇文章我们就来研究…...
mac下Gpt Chrome升级成GptBrowser书签和保存的密码恢复
cd /Users/自己的用户名/Library/Application\ Support/ 目录下有 GPT\ Chrome/ Google/ GptBrowser/ GPT\ Chrome 为原来的chrome浏览器的文件存储目录. GptBrowser 为升级后chrome浏览器存储目录 书签所在的文件 Bookmarks 登录账号Login 相关的文件 拷贝到GptBrow…...
[Redis#6] list | 命令 | 应用 | 消息队列 | 微博 Timeline
目录 List 列表 特点 2. 命令 头插和尾插 下标 range 查询 头删和尾删 LINSERT LLEN LREM LTRIM LSET 阻塞命令 BLPOP BRPOP 操作 总结 3. 内部编码 ziplist(压缩列表) linkedlist(链表) ✔️quicklist(快速链…...
服务器数据恢复—raid6阵列硬盘被误重组为raid5阵列的数据恢复案例
服务器存储数据恢复环境: 存储中有一组由12块硬盘组建的RAID6阵列,上层linux操作系统EXT3文件系统,该存储划分3个LUN。 服务器存储故障&分析: 存储中RAID6阵列不可用。为了抢救数据,运维人员使用原始RAID中的部分…...
Xcode15(iOS17.4)打包的项目在 iOS12 系统上启动崩溃
0x00 启动崩溃 崩溃日志,只有 2 行,看不出啥来。 0x01 默认配置 由于我开发时,使用的 Xcode 14.1,打包在另外一台电脑 Xcode 15.3 Xcode 14.1 Build Settings -> Asset Catalog Compliter - Options Xcode 15.3 Build S…...
Netty的心跳机制怎么实现的?
大家好,我是锋哥。今天分享关于【Netty的心跳机制怎么实现的?】面试题。希望对大家有帮助; Netty的心跳机制怎么实现的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Netty 的心跳机制用于维持客户端和服务器之间的…...
常用函数的使用错题汇总
目录 new/delete malloc/free1. 语言和类型2. 内存分配3. 内存释放4. 安全性和类型安全5. 其他特性总结 线程停止文件流 new/delete malloc/free malloc/free 和 new/delete 是 C/C 中用于动态内存管理的两种方式,它们有一些重要的区别。以下是这两种方式的比较&…...
使用 `aircrack-ng`扫描、获取握手包
使用 aircrack-ng 工具集来扫描 5GHz WiFi 网络的过程与扫描 2.4GHz 网络类似,但需要注意一些特定的配置和命令。以下是一个详细的步骤指南,帮助你在 5GHz 频段上扫描 WiFi 网络并捕获握手包。 ### 前提条件 1. **操作系统**:通常在 Linux 系…...
css—轮播图实现
一、背景 最近和朋友在一起讨论的时候,我们提出了这样的一个提问,难道轮播图的效果只能通过js来实现吗?经过我们的一系列的争论,发现了这是可以通过纯css来实现这一效果的,CSS轮播图也是一种常见的网页展示方式&#x…...
Ardusub源码剖析(1)——AP_Arming_Sub
代码 AP_Arming_Sub.h #pragma once#include <AP_Arming/AP_Arming.h>class AP_Arming_Sub : public AP_Arming { public:AP_Arming_Sub() : AP_Arming() { }/* Do not allow copies */CLASS_NO_COPY(AP_Arming_Sub);bool rc_calibration_checks(bool display_failure)…...
ESP32-S3模组上跑通ES8388(10)
接前一篇文章:ESP32-S3模组上跑通ES8388(9) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析了es8388_init函数中的第3段代码(也是实际与ES8388寄存器打交道的第1段代码),本回继续往下解析。为了便于理…...
AI/ML 基础知识与常用术语全解析
目录 一.引言 二.AI/ML 基础知识 1.人工智能(Artificial Intelligence,AI) (1).定义 (2).发展历程 (3).应用领域 2.机器学习(Machine Learning,ML) (1).定义 (2).学习方式 ①.监督学习 ②.无监督…...
【C#设计模式(15)——命令模式(Command Pattern)】
前言 命令模式的关键通过将请求封装成一个对象,使命令的发送者和接收者解耦。这种方式能更方便地添加新的命令,如执行命令的排队、延迟、撤销和重做等操作。 代码 #region 基础的命令模式 //命令(抽象类) public abstract class …...
Could not resolve com.android.tools.build:gradle:7.4.2.
Android Studio编译项目报错如下,始终无法下载解析7.4.2的gradle classpath A problem occurred configuring root project aistudyclient_questionlib. > Could not resolve all files for configuration :classpath.> Could not resolve com.android.tools…...
uniapp在App端定义全局弹窗,当打开关闭弹窗会触发onShow、onHide生命周期怎么解决?
在uniapp(App端)中实现自定义弹框,可以通过创建一个透明页面来实现。点击进入当前页面时,页面背景会变透明,用户可以根据自己的需求进行自定义,最终效果类似于弹框。 遇到问题:当打开弹窗(进入弹窗页面)就会触发当前页…...
2024 ccpc 辽宁省赛 E(构造 思维?)L(二分+一点点数论知识?)
E 题意: 可以注意到: 我的两种方格都四个方格的大小。 所以 如果存在一种摆放方式 那么 4|nm。 再考虑一种特殊的情况 22 ,此时虽然我的积是4 但是无法摆放的。 1>对于 4 | n,或者 4 | m.我直接摆放第二种方格就可以了。 如果我n 是4 的…...
IIC 随机写+多次写 可以控制写几次
verilog module icc_tx#(parameter SIZE 2 , //用来控制写多少次 比如地址是0000 一个地址只能存放8bit数据 超出指针就会到下一个地址0001parameter CLK_DIV 50_000_000 ,parameter SPEED 100_000 ,parameter LED 50 )( input wire c…...
基于SpringBoot+Vue的汽车票网上预订系统-无偿分享 (附源码+LW+调试)
目录 1. 项目技术 2. 功能菜单 3. 部分功能截图 4. 研究背景 5. 研究目的 6. 可行性分析 6.1 技术可行性 6.2 经济可行性 6.3 操作可行性 7. 系统设计 7.1 概述 7.2 系统流程和逻辑 7.3 系统结构 8. 数据库设计 8.1 数据库ER图 (1)公告信…...
net9 abp vnext 多语言通过数据库动态管理
通过数据库加载实现动态管理,用户可以自己修改界面显示的文本,满足国际化需求 如图所示,前端使用tdesign vnext 新建表TSYS_Localization与TSYS_LocalizationDetail 国旗图标下载网址flag-icons: Free Country Flags in SVG 在Shared下创建下图3个文件 …...
pip安装github上的开源软件包
1、若本机中安装的有git,可使用githttps方式安装 # 以安装pyfolio软件包为例,安装指令如下 pip install githttps://github.com/quantopian/pyfolio.git 2、若本机中没有安装git,可以直接使用软件包的zip地址进行安装 # 以安装pyfolio软件包为例,安装…...
【LeetCode刷题之路】120:三角形最小路径和的两种解法(动态规划优化)
LeetCode刷题记录 🌐 我的博客主页:iiiiiankor🎯 如果你觉得我的内容对你有帮助,不妨点个赞👍、留个评论✍,或者收藏⭐,让我们一起进步!📝 专栏系列:LeetCode…...
架构04-透明多级分流系统
零、文章目录 架构04-透明多级分流系统 1、透明多级分流系统 (1)概述 **定义:**透明多级分流系统是指在用户请求从客户端发出到最终查询或修改数据库信息的过程中,通过多个技术部件对流量进行合理分配,以提高系统的…...
云原生后端开发:构建现代化可扩展的服务
随着微服务架构的普及和容器化技术的成熟,云原生后端开发成为了构建现代化、可扩展系统的关键。本文将从云原生理念出发,结合实际案例,探讨如何使用 Kubernetes、服务网格、微服务架构等技术构建高效的云原生后端。 一、云原生的核心理念 1.…...
在Windows和Linux系统上获取网卡MAC地址及相关信息所有常用方法整理
摘要 在网络管理和故障排除中,了解如何获取网卡的MAC地址、IP地址以及网卡名称是系统管理员必备的技能。本文将介绍在Windows和Linux系统上手动获取网卡MAC地址的方法,并提供脚本以自动化获取服务器中网卡信息的过程。这些技巧和工具将帮助新手系统管理…...
制作苹果IOS.APP所使用步骤和方法-有步骤视情况待完善
1.获取开发工具 首先,您需要下载并安装Xcode。Xcode是苹果开发iOS和macOS应用程序的官方集成开发环境(IDE)。它包含了必要的工具,例如代码编辑器、调试器、编译器和界面构建器。Xcode可在Mac App Store中免费下载。 2.学习Swift或…...
【conda】全面解析 Conda 配置文件:从完整示例到最佳实践
目录 引言一、Conda 配置文件示例1.1 中英文注释示例1.2 文件编码格式 二、详细解释2.1 ssl_verify: true2.2 channels2.3 envs_dirs2.4 pkgs_dirs2.5 custom_channels2.6 remote_read_timeout_secs 和 remote_connect_timeout_secs2.7 show_channel_urls2.8 default_packages2…...
ffmpeg命令详解
原文网址:ffmpeg命令详解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍ffmpeg命令的用法。 命令示例 1.mp4和avi的基本互转 ffmpeg -i D:\input.mp4 E:\output.avi ffmpeg -i D:\input.avi E:\output.mp4 -i 表示input,即输入。后面填一个输入地址和一…...
asyncio.run() 里面嵌套 asyncio.run() 可以吗?
[TOC](asyncio.run() 里面嵌套 asyncio.run() 可以吗?) 在 Python 的异步编程中,asyncio 是一个非常重要的模块,它提供了编写单线程并发代码的基础设施。asyncio.run() 是一个方便的函数,用于运行一个协程并管理事件循环的生命周…...
flutter in_app_purchase google支付 PG-GEMF-01错误
问题:PG-GEMF-01错误 flutter 使用in_app_purchase插件升降级订阅时报错PG-GEMF-01。 解决方案: 升降级订阅时,确保不调用 MethodCallHandlerImpl.java文件中的 setObfuscatedAccountId()方法、setObfuscatedProfileId()方法 原因…...
Flink 离线计算
文章目录 一、样例一:读 csv 文件生成 csv 文件二、样例二:读 starrocks 写 starrocks三、样例三:DataSet、Table Sql 处理后写入 StarRocks四、遇到的坑 <dependency><groupId>org.apache.flink</groupId><artifactId&…...
排序算法之插入排序篇
插入排序 思路: 就是将没有排序的元素逐步地插入到已经排好序的元素后面,保持元素的有序 视频的实现过程如下: 插入排序全过程 代码实现过程如下: public static void Insertion(int[] arr) { for (int i 1; i < arr.length…...
(11)(2.2) BLHeli32 and BLHeli_S ESCs(二)
文章目录 前言 1 传递支持 前言 BLHeli 固件和配置应用程序的开发是为了允许配置 ESC 并提供额外功能。带有此固件的 ESC 允许配置定时、电机方向、LED、电机驱动频率等。在尝试使用 BLHeli 之前,请按照 DShot 设置说明进行操作(DShot setup instructions)。 1 传…...
Unity之一键创建自定义Package包
内容将会持续更新,有错误的地方欢迎指正,谢谢! Unity之一键创建自定义Package包 TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! …...
【AI】JetsonNano启动时报错:soctherm OC ALARM
1、问题描述 将JetsonNano烧写SD卡镜像为Ubuntu20.04后,启动时报错:soctherm OC ALARM,启动失败;然后系统一直重启 2、原因分析 “soctherm OC ALARM”是检测到系统温度超过安全阈值时发出的过热警告。 “soctherm”代表系统…...
道路机器人识别交通灯,马路,左右转,黄线,人行道,机器人等路面导航标志识别-使用YOLO标记
数据集分割 train组66% 268图片 validation集22% 91图片 test集12% 48图片 预处理 没有采用任何预处理步骤。 增强 未应用任何增强。 数据集图片: 交通灯 马路 右转 向右掉头 机器人识别 人行横道 黄线 直行或右转 数据集下载: 道路…...
电子应用设计方案-31:智能AI音响系统方案设计
智能 AI 音响系统方案设计 一、引言 智能 AI 音响作为一种新兴的智能家居设备,通过融合语音识别、自然语言处理、音频播放等技术,为用户提供便捷的语音交互服务和高品质的音乐体验。本方案旨在设计一款功能强大、性能稳定、用户体验良好的智能 AI 音响系…...
SQL优化与性能——数据库设计优化
数据库设计优化是提高数据库性能、确保数据一致性和支持业务增长的关键环节。无论是大型企业应用还是小型项目,合理的数据库设计都能够显著提升系统性能、减少冗余数据、优化查询响应时间,并降低维护成本。本章将深入探讨数据库设计中的几个关键技术要点…...
脑网络组织与心跳动力学之间的耦合测量
摘要 近年来,人们对脑心相互作用的研究兴趣日益浓厚。许多研究提出了新的方法来探究大脑与心脏如何通信,从而对一些神经功能有了新的认识。然而,大多数框架只关注单个脑区域与心跳动态之间的相互作用,忽略了大脑的功能网络会随着…...
图像显示的是矩阵的行和列,修改为坐标范围。
x 3; y 3; f1x x^2 y^2; guance1 f1x; F (x, y) sqrt((x.^2 y.^2 - guance1).^2); % 使用点乘 [x, y] meshgrid(0:1:5, 0:1:5); Z F(x, y); figure; imagesc(Z); % 由于 imagesc 使用矩阵索引作为坐标,我们需要手动添加刻度 % 这里我们假设 x 和 y 的范围…...