Flutter实现局部刷新的几种方式
目录
前言
1.局部刷新的重要性
1.概念
2.重要性
2.局部刷新实现的几种方式
1.使用setState方法进行局部刷新
2.使用StatefulWidget和InheritedWidget局部刷新UI
3.ValueNotifier和ValueListenableBuilder
4.StreamBuilder
5.Provider
6.GetX
7.使用GlobalKey

前言
在 Flutter 中,状态管理指的是如何管理和更新应用中的数据状态,并且根据状态的变化来更新 UI。有效的状态管理能够帮助开发者创建更高效、更可维护的应用。
setState是 Flutter 中最基本的状态管理方法,当状态发生变更的时候,会通知框架重新构建UI。当然我们知道当我们调用setState方法的时候,页面会重绘,当页面布局比较复杂的时候,有时候我们仅仅需要更新某个单独的UI,这个时候如果使用setState方法,则会有比较大的性能消耗去重绘当前页面UI.
那么Flutter中有哪些方法可以局部刷新UI呢,这篇博客列举了Flutter实现局部刷新的几种方式。
1.局部刷新的重要性
1.概念
局部刷新指的是只刷新界面的一部分,而不是整个页面。这样可以提高性能和用户体验。
2.重要性
- 避免不必要的重绘,提高性能
- 提供更流畅的用户体验
- 减少资源消耗
2.局部刷新实现的几种方式
1.通过setState局部刷新
setState是Flutter 中最常用的状态管理方法,用于通知框架状态发生变化,导致界面重建。
我们创建Flutter工程的时候,系统默认生成的计时器的例子,就是setState局部刷新的例子。
import 'package:flutter/material.dart';class StatePartialRefreshPage extends StatefulWidget {const StatePartialRefreshPage({super.key});@overrideState<StatePartialRefreshPage> createState() =>_StatePartialRefreshPageState();
}class _StatePartialRefreshPageState extends State<StatePartialRefreshPage> {int _count = 0;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("setState局部刷新",style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('您点击了$_count次',style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),const SizedBox(height: 20,),FilledButton(onPressed: () {setState(() {_count++;});},child: const Icon(Icons.add)),],)),);}
}

图1.setState局部刷新
当页面比较简单的时候,可以直接使用setState方法局部刷新UI。
使用场景:简单的状态变化,如按钮点击计数、开关状态等。
注意事项:
- 频繁调用 setState 可能导致性能问题
- 避免在 build 方法中调用 setState
2.使用StatefulWidget和InheritedWidget局部刷新UI
StatefulWidget 是具有状态的组件,InheritedWidget 用于在组件树中共享数据。
当我们需要共享数据的时候,可以考虑StatefulWidget和InheritedWidget局部刷新UI.
完整代码如下:

图2.共享数据的方式刷新UI
import 'package:flutter/material.dart';class MyInheritedWidget extends InheritedWidget {final int counter;const MyInheritedWidget({super.key,required this.counter,required super.child,});@overridebool updateShouldNotify(covariant InheritedWidget oldWidget) {return true;}static MyInheritedWidget? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();}
}class InheritedWidgetPage extends StatefulWidget {final String title;const InheritedWidgetPage({super.key, required this.title});@overrideState<InheritedWidgetPage> createState() => _InheritedWidgetPageState();
}class _InheritedWidgetPageState extends State<InheritedWidgetPage> {int counter = 0;void _incrementCounter() {setState(() {counter++;});}@overrideWidget build(BuildContext context) {return MyInheritedWidget(counter: counter,child: Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(children: [const Divider(),const CounterDisplay(),const SizedBox(height: 20),ElevatedButton(onPressed: _incrementCounter,child: const Text('add'),),],),),),);}
}class CounterDisplay extends StatelessWidget {const CounterDisplay({super.key});@overrideWidget build(BuildContext context) {final inheritedWidget = MyInheritedWidget.of(context);return Text('点击次数: ${inheritedWidget?.counter}');}
}
这种方式主要使用场景如下:组件树中共享状态时,如主题、语言设置等。
优点就是数据共享方便,代码简介
缺点就是使用复杂,性能可能收到影响
3.ValueNotifier和ValueListenableBuilder
ValueNotifier 是一个简单的状态管理工具,ValueListenableBuilder 用于监听 ValueNotifier 的变化。
使用方法也非常简单:
1.实例化ValueNotifier
2.要监听的Widget对象是用ValueListenableBuilder包裹起来
3.事件触发数据的变更方法
这种方式和前几种方式比较非常的简单易容,性能也很高
缺点:只能处理简单的状态变化
完整的代码如下:
import 'package:flutter/material.dart';class ValueNotifierPage extends StatefulWidget {final String title;const ValueNotifierPage({super.key, required this.title});@overrideState<ValueNotifierPage> createState() => _ValueNotifierPageState();
}class _ValueNotifierPageState extends State<ValueNotifierPage> {final ValueNotifier<int> _counter = ValueNotifier<int>(0);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: ValueListenableBuilder<int>(valueListenable: _counter,builder: (context, value, child) {return Text('您点击了$value次',style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),);},)),floatingActionButton: FloatingActionButton(child: const Icon(Icons.add),onPressed: () {_counter.value ++;},));}
}
4.StreamBuilder
Stream是一种用于传递异步事件的对象,可以通过StreamController发送事件。在需要刷新UI的地方,可以发送一个事件到Stream,然后使用StreamBuilder监听该Stream,当收到新的事件时,StreamBuilder会自动重新构建UI。这种方式适用于需要监听多个异步事件的情况。
当我们需要处理异步数据流,如网络请求、实时数据等的时候,可以考虑使用StreamBuilder。例如在下面的例子中,我们写了一个模拟网络请求的异步方法,当网络请求没返回正确结果的时候,我们可以加载进度条。
这种方式的优点就是可以对异步请求进行更加精准的控制,例如网络请求的状态等。却迪奥就是复杂度比较高,可能需要更多的代码。
完整的代码如下:
import 'dart:async';
import 'package:flutter/material.dart';class StreamBuilderRefreshUIPage extends StatefulWidget {final String title;const StreamBuilderRefreshUIPage({super.key, required this.title});@overrideState<StreamBuilderRefreshUIPage> createState() =>_StreamBuilderRefreshUIPageState();
}class _StreamBuilderRefreshUIPageState extends State<StreamBuilderRefreshUIPage> {late Future<String> _data;Future<String> fetchData() async {// 模拟网络请求延迟await Future.delayed(const Duration(seconds: 2));// 返回模拟数据return 'Hello, Flutter!';}@overridevoid initState() {// TODO: implement initStatesuper.initState();_data = fetchData();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: FutureBuilder<String>(future: _data,builder: (context, snapshot) {if (snapshot.connectionState == ConnectionState.waiting) {return const CircularProgressIndicator();} else if (snapshot.hasError) {return Text('Error: ${snapshot.error}');} else {return Text('Data: ${snapshot.data}');}},),),floatingActionButton: FloatingActionButton(onPressed: fetchData,tooltip: 'Increment',child: const Icon(Icons.add),),);}
}
5.Provider
Provider 是 Flutter 推荐的状态管理解决方案,Consumer 用于读取和监听状态。
我们还以定时器为例。
1.首先我们导入Provider.
provider: ^6.1.2
2.自定义ChangeNotifier类。
ChangeNotifier 是 Flutter SDK 中的一个简单的类。它用于向监听器发送通知。换言之,如果被定义为 ChangeNotifier,你可以订阅它的状态变化。(这和大家所熟悉的观察者模式相类似)。
在我们要实现的代码中,有两个变量_counter1和_counter2.代码定义如下:
class CounterModel extends ChangeNotifier {int _counter1 = 0;int _counter2 = 0;void addCounter1(){debugPrint('counter:$_counter1');_counter1 += 1;notifyListeners();}void addCounter2(){debugPrint('counter:$_counter2');_counter2 += 1;notifyListeners();}
}
3.使用Customer把我们要刷新的Widget包裹起来
Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter1}'),ElevatedButton(onPressed: (){counterModel.addCounter1();}, child: const Icon(Icons.add),),],);},),
4.完整代码如下:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';class ProviderRefreshPage extends StatefulWidget {final String title;const ProviderRefreshPage({super.key, required this.title});@overrideState<ProviderRefreshPage> createState() => _ProviderRefreshPageState();
}class CounterModel extends ChangeNotifier {int _counter1 = 0;int _counter2 = 0;void addCounter1(){debugPrint('counter:$_counter1');_counter1 += 1;notifyListeners();}void addCounter2(){debugPrint('counter:$_counter2');_counter2 += 1;notifyListeners();}
}class _ProviderRefreshPageState extends State<ProviderRefreshPage> {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold),),Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter1}'),ElevatedButton(onPressed: (){counterModel.addCounter1();}, child: const Icon(Icons.add),),],);},),Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter2}'),ElevatedButton(onPressed: (){counterModel.addCounter2();}, child: const Icon(Icons.add),),],);},),const Divider(height: 20,),],),),);}
}
6.GetX
我们还可以使用GetX实现UI的局部刷新。
首先安装GetX:
get: ^4.6.6
然后我们把变量封装在GetxController中.
class CounterManagerController extends GetxController {final counter1 = 0.obs;final counter2 = 0.obs;void incrementCount1() {counter1.value++;}void incrementCount2() {counter2.value++;}
}
再使用Obx把需要显示逻辑的Widget包裹起来。
Obx(()=> Text('计数器1个数: ${controller.counter2.value}'))
完整的代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';class CounterManagerController extends GetxController {final counter1 = 0.obs;final counter2 = 0.obs;void incrementCount1() {counter1.value++;}void incrementCount2() {counter2.value++;}
}class GetXRefreshUIPage extends StatelessWidget {final String title;const GetXRefreshUIPage({super.key, required this.title});@overrideWidget build(BuildContext context) {final CounterManagerController controller = Get.put(CounterManagerController());return Scaffold(appBar: AppBar(title: Text(title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Obx(()=> Text('计数器1个数: ${controller.counter1.value}')),ElevatedButton(onPressed: () {controller.incrementCount1();},child: const Icon(Icons.add),),],),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Obx(()=> Text('计数器1个数: ${controller.counter2.value}')),ElevatedButton(onPressed: () {controller.incrementCount2();},child: const Icon(Icons.add),),],),const Divider(height: 20,),],),),);}
}
当然GetX中实现局部刷新的方式还有其它几种写法,大家可以看一下它的文档。这里只是提供了其中的一种实现思路。
7.通过GlobalKey局部刷新
上述三种实现方式都是通过框架实现的,如果你不想导入这个框架,我们可以使用GlobalKey来实现UI的局部刷新功能。
在整个应用程序中是唯一的Key GlobalKey可以唯一标识元素,GlobalKey提供了对这些元素相关联的访问,比如BuildContext。对于StatefulWidgets,GlobalKey也提供对State的访问。
在我们的计时器的demo中,如果我们通过GlobalKey的方式局部刷新UI,首先我们把要局部刷新的Widget提出来,单独封装成一个组件。
完整代码如下,我们封装要局部刷新的Widget,并且提供一个刷新内部数据的接口,onPressed.
class CounterText extends StatefulWidget {const CounterText(Key key) : super(key: key);@overrideState<StatefulWidget> createState() {return CounterTextState();}
}class CounterTextState extends State<CounterText> {String _text="0";@overrideWidget build(BuildContext context) {return Center(child: Text(_text,style: const TextStyle(fontSize: 20),),);}void onPressed(int count) {setState(() {_text = count.toString();});}
}
然后在我们的主界面实例化GlobaKey:
int _count = 0;int _count2 = 0;GlobalKey<CounterTextState> textKey = GlobalKey();GlobalKey<CounterTextState> textKey2 = GlobalKey();
在需要刷新UI的事件中,通过GlobalKey调用上一步提供的接口,刷新即可。
完整代码如下:
import 'package:flutter/material.dart';class GlobalKeyRefreshPage extends StatefulWidget {final String title;const GlobalKeyRefreshPage({super.key, required this.title});@overrideState<GlobalKeyRefreshPage> createState() => _GlobalKeyRefreshPageState();
}class _GlobalKeyRefreshPageState extends State<GlobalKeyRefreshPage> {int _count = 0;int _count2 = 0;
//包裹你定义的需要更新的weightGlobalKey<CounterTextState> textKey = GlobalKey();GlobalKey<CounterTextState> textKey2 = GlobalKey();@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [CounterText(textKey),ElevatedButton(onPressed: () {_count++;textKey.currentState?.onPressed(_count);},child: const Icon(Icons.add),),],),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [CounterText(textKey2),ElevatedButton(onPressed: () {_count2++;textKey2.currentState?.onPressed(_count2);},child: const Icon(Icons.add),),],),const Divider(height: 20,),],),),);}
}class CounterText extends StatefulWidget {const CounterText(Key key) : super(key: key);@overrideState<StatefulWidget> createState() {return CounterTextState();}
}class CounterTextState extends State<CounterText> {String _text="0";@overrideWidget build(BuildContext context) {return Center(child: Text(_text,style: const TextStyle(fontSize: 20),),);}void onPressed(int count) {setState(() {_text = count.toString();});}
}
相关文章:
Flutter实现局部刷新的几种方式
目录 前言 1.局部刷新的重要性 1.概念 2.重要性 2.局部刷新实现的几种方式 1.使用setState方法进行局部刷新 2.使用StatefulWidget和InheritedWidget局部刷新UI 3.ValueNotifier和ValueListenableBuilder 4.StreamBuilder 5.Provider 6.GetX 7.使用GlobalKey 前言 …...
力扣题解(回文子串)
647. 回文子串 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 思路: 首先,本题要求的是数目,而且不要求没…...
对数的基本概念
概念 在数学中,对数是对求幂的逆运算,正如除法是乘法的倒数,反之亦然。这意味着一个数字的对数是必须产生过另一个固定数字(基数)的指数 如果a的x次方等于N(a > 0, 且a不等于1),那么数x叫做以a为底N的…...
C双指针滑动窗口算法
这也许是双指针技巧的最⾼境界了,如果掌握了此算法,可以解决⼀⼤类⼦字符串匹配的问题 原理 1、我们在字符串 S 中使⽤双指针中的左右指针技巧,初始化 left right 0,把索引闭区间 [left, right] 称为⼀个「窗⼝」。 2、我们先…...
WPF学习(6) -- WPF命令和通知
一 、WPF命令 1.ICommand代码 创建一个文件夹和文件 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input;namespace 学习.Command {public class MyCommand : ICommand{Acti…...
升级到LVGL9的一些变化(后续发现再补充)
目录 一、主要内容 二、新增内容 三、常规API变化 四、Display API(显示API) 五、其他 最近在将LVGL8的demo代码升级到LVGL9,带来不小的变化 ,收集网上的一些内容,整理如下: 一、主要内容 二、新增内容 三、常规API变化 四、Display API(显示API)...
当在多线程环境中使用 C++进行编程时,怎样确保线程安全以及如何处理线程之间的同步和通信?
在C中确保线程安全性和处理线程之间的同步和通信有多种方法。下面是一些常用的技术和技巧: 互斥锁:使用互斥锁可以确保只有一个线程可以访问共享资源。在访问共享资源之前获取锁,在完成后释放锁。这可以防止多个线程同时访问同一份数据&#…...
博物馆地图导航系统:高精度地图引擎与AR/VR融合,实现博物馆数字化转型
在人民日益追求精神文化的时代下,博物馆作为传承与展示人类文明的璀璨殿堂,其重要性不言而喻。然而,随着博物馆规模的不断扩大和藏品种类的日益丰富,游客在享受知识盛宴的同时,也面临着“迷路”与“错过”的困扰。博物…...
liunx作业笔记1
一、选择题(每小题2分,共20分) 1、下列变量命名为Shell中无效变量名的是( D ) A、v_ar1 B、var1 C、_var D、*var 变量名以字母开头,包含下划线和数字。 2、关于expr命令的使用下列命令中得数不等于…...
大话C语言:第31篇 指针和数组的关系
数组在内存中是连续存放的,其名称代表了数组首元素的首地址,该地址是常量, 也就是一个指向数组首元素的指针。因此,指针和数组有着密切的关系: 可以使用指针来访问和操作数组中的元素。通过指针的算术运算,…...
Mysql-索引应用
目录 索引应用 MySQL有哪些索引? 普通索引和唯一索引有什么区别? 哪个更新性能更好? 、 聚簇索引的主键索引怎么设置? 追问:假如你不设置会怎么样? 我们一般选择什么样的字段来建立索引? 索引越多越好吗? 索引怎么优化? (覆盖索引优化、防止索引失效、…...
Facebook 开源计算机视觉 (CV) 和 增强现实 (AR) 框架 Ocean
Ocean 是一个独立于平台的框架,支持所有主要操作系统,包括 iOS、Android、Quest、macOS、Windows 和 Linux。它旨在彻底改变计算机视觉和混合现实应用程序的开发。 Ocean 主要使用 C 编写,包括计算机视觉、几何、媒体处理、网络和渲染&#x…...
【接口自动化_13课_接口自动化总结】
一、自我介绍 二、项目介绍 自己的职责、项目流程 1)功能测试,怎么设计用例的--测试策略 2)功能测试为什么还有代码实现,能用工具实现,为什么还用代码实现。 基本情况 项目名称:项目类型:项目测试人员…...
安防管理平台LntonCVS视频汇聚融合云平台智慧火电厂安全生产管理应用方案
中国的电力产业作为国民经济发展的重要能源支柱,被视为国民经济的基础产业之一。目前,我国主要依赖火力发电,主要燃料包括煤炭、石油和天然气等,通过燃烧转化为动能,再转变为电能输送至全国各地。火力发电量占全国发电…...
【Web性能优化】在Vue项目中使用defer优化白屏,秒加载!
历史小剧场 相对而言,流芳千古的钱谦益先生,就有点儿区别了,除了家产外,也很能挣钱(怎么来的就别说了),经常出没红灯区,六十岁多了,还娶了柳如是,明朝亡时&am…...
springboot上传图片
前端的name的值必须要和后端的MultipartFile 形参名一致 存储本地...
python入门:python及PyCharm安装
前言 我们将详细介绍如何在系统上安装Python及使用PyCharm创建项目的具体流程。Python是一种广泛应用的编程语言,其简单易学的特点使其成为初学者的首选。而PyCharm则是一个功能强大的Python IDE,可以极大地提高开发效率。通过本文,你将学会…...
链接追踪系列-04.linux服务器docker安装elk
[rootVM-24-17-centos ~]# cat /proc/sys/vm/max_map_count 65530 [rootVM-24-17-centos ~]# sysctl -w vm.max_map_count262144 vm.max_map_count 262144 #先创建出相应目录:/opt/dockerV/es/…docker run -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -d -p 92…...
深入探讨微服务架构设计模式与常见实践
深入探讨微服务架构设计模式与常见实践 引言 在现代软件开发中,微服务架构因其灵活性和可扩展性被广泛采用。本文将深入探讨微服务架构的设计理念和常见模式,详细介绍每个模式的实现方法,并分别提供适用于Ubuntu和CentOS的具体命令和代码示…...
【java】合并数组的两种方法
文章目录 1.利用arraycope的方法2.将两数组合并 ,在排序 1.利用arraycope的方法 public class MergeArr {public static void main(String[] args) {int[] arr1 {1,2,3,4,5,6};int[] arr2 {7,8,9};//合并完的数组int[] arr3 new int[arr1.length arr2.length];…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
