Flutter路由

路由作为一种页面切换的能力,非常重要。Flutter 中路由管理有几个重要的点。

Navigator 1.0:Flutter 早期路由系统,侧重于移动端 ,命令式编程风格,使用 Navigator.push() 和 Navigator.pop() 等方法来管理路由栈。

Navigator 2.0:Flutter1.22 版本以后新增,侧重于桌面端/网页端,声明式编程风格,使用 Router 和 RouteInformationParser 等类来描述和管理路由树。

Flutter路由重要的类

1.Route:应用程序页面的抽象, Navigator 管理 Route。

2.Navigator:负责路由管理的重要类,通过 push 和 pop 进行页面跳转。

Flutter 跳转方式

动态路由

适于单次导航的场景,直接在代码中创建和导航的路由。

Navigator.push(context,MaterialPageRoute(builder: (context) => RouterPageA()));

   Navigator.pop(context);
import 'package:flutter/material.dart';import 'dart_test_router1.dart';class TestRouterPage extends StatelessWidget {const TestRouterPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test Navigator"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("Test MaterialPageRoute"),ElevatedButton(onPressed: () {Navigator.push(context,MaterialPageRoute(builder: (context) => RouterPageA()));},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
}
import 'package:flutter/material.dart';class RouterPageA extends StatelessWidget {const RouterPageA({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("RouterPageA"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("Test Navigator.pop"),ElevatedButton(onPressed: () {Navigator.pop(context);},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
}

Navigator.push有两个参数,一个是BuildContext,另一个是Route。代码中使用的是MaterialPageRoute,执行与对应平台风格一致的切换动画(android 与 ios平台不同)。如果使用 CupertinoPageRoute,页面切换效果是左右滑动。

PageRoute可以自定义,实现自定义页面切换的动画和行为。如果想自定义下过渡动画,使用 PageRouteBuilder 创建自定义路由,通过 pageBuilder 和 transitionsBuilder 属性来定义页面和过渡动画。

通过 pageBuilder 实现页面渐入动画

                Navigator.of(context).push(PageRouteBuilder(pageBuilder: (context, animation, secondaryAnimation) {return FadeTransition(opacity: animation, child: const RouterPageA());}));

pageBuilder + transitionsBuilder 实现过渡动画

Navigator.of(context).push(PageRouteBuilder(pageBuilder: (context, animation, secondaryAnimation) =>const RouterPageA(),transitionsBuilder:(context, animation, secondaryAnimation, child) {//动画的起始位置,轴y方向屏幕下侧偏移起点var start = const Offset(0, 1);//动画的结束位置,0表示没有偏移var end = Offset.zero;//动画曲线,easeInOut 表示开始慢,中间加速,结束慢var curve = Curves.easeInOut;// 创建一个从begin到end的补间动画,.chain 表示与曲线结合var tween = Tween(begin: start, end: end).chain(CurveTween(curve: curve));// SlideTransition 是一个动画Widgetreturn SlideTransition(position: animation.drive(tween), child: child);}));

 静态路由

静态路由需要提前注册,首先给每个路由定义一个名称,通过这个名称来导航到对应的路由。

在应用根级别 (MaterialApp 或者 CupertinoApp ) 中定义路由,使用routes参数将路由名称映射到对应的Widget。

不带参数与返回值案例

Navigator.of(context).pushNamed("/dart_test_router1");
import 'package:flutter/material.dart';import 'dart_test_router1.dart';class TestStaticRouterPage extends StatelessWidget {const TestStaticRouterPage({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: "Test Router Demo",theme: ThemeData(useMaterial3: false,primarySwatch: Colors.blue,textButtonTheme: const TextButtonThemeData(style: ButtonStyle(splashFactory: NoSplash.splashFactory),),),home: const RealTestStaticRouterPage(),routes: {//  "/": (context) => const RealTestStaticRouterPage(),"/dart_test_router1": (context) => const RouterPageA()},// initialRoute: "/",);}
}class RealTestStaticRouterPage extends StatelessWidget {const RealTestStaticRouterPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("TEST STATIC ROUTER PAGE"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("Test Static Router Page"),ElevatedButton(onPressed: () {Navigator.of(context).pushNamed("/dart_test_router1");},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}

带参数与返回值

import 'package:flutter/material.dart';import 'dart_test_router1.dart';
import 'dart_test_router3.dart';class TestStaticRouterPage extends StatelessWidget {const TestStaticRouterPage({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: "Test Router Demo",theme: ThemeData(useMaterial3: false,primarySwatch: Colors.blue,textButtonTheme: const TextButtonThemeData(// 鍘绘帀 TextButton 鐨勬按娉㈢汗鏁堟灉style: ButtonStyle(splashFactory: NoSplash.splashFactory),),),home: const RealTestStaticRouterPage(),routes: {//  "/": (context) => const RealTestStaticRouterPage(),"/dart_test_router1": (context) => const RouterPageA(),"/dart_test_router3": (context) => const RouterPage3()},// initialRoute: "/",);}
}class RealTestStaticRouterPage extends StatelessWidget {const RealTestStaticRouterPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("TEST STATIC ROUTER PAGE"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("Test Static Router Page"),ElevatedButton(onPressed: () async {var result = await Navigator.of(context).pushNamed("/dart_test_router3",arguments: {"title": "Hello"});print(result);},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
import 'package:flutter/material.dart';class RouterPage3 extends StatefulWidget {const RouterPage3({super.key});@overrideState<StatefulWidget> createState() {return _RouterPage3State();}
}class _RouterPage3State extends State<RouterPage3> {@overrideWidget build(BuildContext context) {var args =ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>?;final title = args?['title'] ?? "DEFAULT TITLE";return Scaffold(appBar: AppBar(title: Text("RouterPageA"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text("GET TITLE===========銆?title"),ElevatedButton(onPressed: () {Navigator.pop(context, "I went from RouterPage3");},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
}

 

2024-09-12 10:01:46.569 25438-25629 flutter  I  I went from RouterPage3

路由操作

路由替换

像登录页跳首页的场景,我们希望页面跳转成功后,回到上上个页面。我们可以通过pushReplacement、pushReplacementNamed实现。

API一:动态路由替换

Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => RouterPageA()));

API二:静态路由替换

         var result = await Navigator.of(context).pushReplacementNamed("/dart_test_router3",arguments: {"title": "Hello"});

新路由入栈+移除之前的路由,直到条件满足

pushAndRemoveUntil 将给定路由推送给Navigator,删除先前的路由,直到该函数的参数predicate返回true为才停止。

import 'package:flutter/material.dart';import 'dart_test_router1.dart';
import 'dart_test_router3.dart';class TestRouterPage4 extends StatelessWidget {const TestRouterPage4({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: "Test pushAndRemoveUntil",theme: ThemeData(useMaterial3: false,primarySwatch: Colors.blue,textButtonTheme: const TextButtonThemeData(style: ButtonStyle(splashFactory: NoSplash.splashFactory),)),home: const RealTestRouterPage4(),);}
}class RealTestRouterPage4 extends StatelessWidget {const RealTestRouterPage4({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test pushAndRemoveUntil"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("test pushAndRemoveUntil"),ElevatedButton(onPressed: () {Navigator.pushAndRemoveUntil(context,MaterialPageRoute(builder: (context) => RouterPageA()),(Route<dynamic> route) => route.isFirst);},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)]),),);}
}

这个方式是跳转到某个页面,然后移除路由直到...为止

路由出栈,直到条件满足

在flutter 路由跳转中,我们想要回到特定的一个页面 比如:从 A -> B-> C ->D,我们向从 D页面 pop至 B 页面。我们可以使用 popUtil方法回到 B 页面。

popUntil 反复执行pop 直到该函数的参数predicate返回true为止。

import 'package:flutter/material.dart';import 'dart_test_router6.dart';class TestRouterPage5 extends StatelessWidget {const TestRouterPage5({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: "Test popUntil TestRouterPage5",theme: ThemeData(useMaterial3: false,primarySwatch: Colors.blue,textButtonTheme: const TextButtonThemeData(style: ButtonStyle(splashFactory: NoSplash.splashFactory),)),home: const RealTestRouterPage5(),);}
}class RealTestRouterPage5 extends StatelessWidget {const RealTestRouterPage5({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test popUntil TestRouterPage5"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("test popUntil TestRouterPage5"),ElevatedButton(onPressed: () {Navigator.push(context,MaterialPageRoute(builder: (context) => TestRouterPage6()));},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)]),),);}
}
import 'package:flutter/material.dart';import 'dart_test_router7.dart';class TestRouterPage6 extends StatelessWidget {const TestRouterPage6({super.key});@overrideWidget build(BuildContext context) {return RealTestRouterPage6();}
}class RealTestRouterPage6 extends StatelessWidget {const RealTestRouterPage6({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test popUntil TestRouterPage6"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("test popUntil TestRouterPage6"),ElevatedButton(onPressed: () {Navigator.push(context,MaterialPageRoute(builder: (context) => TestRouterPage7()));},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)]),),);}
}
import 'package:flutter/material.dart';class TestRouterPage7 extends StatelessWidget {const TestRouterPage7({super.key});@overrideWidget build(BuildContext context) {return RealTestRouterPage7();}
}class RealTestRouterPage7 extends StatelessWidget {const RealTestRouterPage7({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test popUntil TestRouterPage7"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("test popUntil TestRouterPage7"),ElevatedButton(onPressed: () {Navigator.of(context).popUntil((Route<dynamic> route) => route.isFirst);},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)]),),);}
}

上面的代码中调用Navigator.of(context)
                      .popUntil((Route<dynamic> route) => route.isFirst);直接回到了 TestRouterPage5。

 

删除指定路由

获得当前路由

ModalRoute.of(context);

 移除指定路由


if (route != null) {Navigator.of(context).removeRoute(route);
}

移除指定路由下方的单个路由

if (route != null) {Navigator.of(context).removeRouteBelow(route);
}

页面传参与数据回传

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:gsy_flutter_demo/widget/dart_test_router2.dart';import 'dart_test_router1.dart';class TestRouterPage extends StatelessWidget {const TestRouterPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("Test Navigator"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[const Text("Test MaterialPageRoute"),ElevatedButton(onPressed: () async {String backContent = await Navigator.of(context).push(MaterialPageRoute(builder: (context) => RouterPage2(title: "Custom Title")));print(backContent);},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
}
import 'package:flutter/material.dart';class RouterPage2 extends StatefulWidget {final String title;const RouterPage2({super.key, required this.title});@overrideState<StatefulWidget> createState() {return _RouterPage2State();}
}class _RouterPage2State extends State<RouterPage2> {@overrideWidget build(BuildContext context) {var widgitTitle = widget.title;return Scaffold(appBar: AppBar(title: Text("RouterPageA"),),body: Container(alignment: Alignment.center,margin: const EdgeInsets.all(10),child: Column(crossAxisAlignment: CrossAxisAlignment.center,mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[Text("GET TITLE===========銆?widgitTitle"),ElevatedButton(onPressed: () {Navigator.pop(context, "I went from RouterPageA");},child: Text("Click ElevatedButton"),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,elevation: 10,minimumSize: Size(double.infinity, 50),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),)],),),);}
}

2024-09-11 14:51:16.211 24765-24840 flutter I  I went from RouterPageA


 

Navigator  的工作流程

Navigator  的核心是对路由栈的管理。当你调用 Navigator.push 时,一个新的路由被创建并推入栈顶;当你调用 Navigator.pop 时,栈顶的路由被移除。

  const Navigator({super.key,this.pages = const <Page<dynamic>>[],this.onPopPage,this.initialRoute,this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,this.onGenerateRoute,this.onUnknownRoute,this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),this.reportsRouteUpdateToEngine = false,this.clipBehavior = Clip.hardEdge,this.observers = const <NavigatorObserver>[],this.requestFocus = true,this.restorationScopeId,this.routeTraversalEdgeBehavior = kDefaultRouteTraversalEdgeBehavior,});

Navigator.push 

#Navigator.push

  @optionalTypeArgsstatic Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {return Navigator.of(context).push(route);}

Navigator.push 调用Navigator.of(context).push(route),内部 调用NavigatorState 的 push 方法:

  @optionalTypeArgsFuture<T?> push<T extends Object?>(Route<T> route) {_pushEntry(_RouteEntry(route, pageBased: false, initialState: _RouteLifecycle.push));return route.popped;}

 #NavigatorState

  void _pushEntry(_RouteEntry entry) {assert(!_debugLocked);assert(() {_debugLocked = true;return true;}());assert(entry.route._navigator == null);assert(entry.currentState == _RouteLifecycle.push);_history.add(entry);_flushHistoryUpdates();assert(() {_debugLocked = false;return true;}());_afterNavigation(entry.route);}

这里发生了一系列操作:

  • _history.add(route) : 将 新路由 添加到 路由栈 中。
  • route.install() : 安装路由,将页面挂载到 widget 树上。
  • route.didPush() : 通知 路由 已经被推入 栈顶 。
  • _cancelActivePointers() : 取消所有正在进行的触摸事件,防止发生意外事件。
  • route.didChange() : 通知 路由 状态发生变化。

push 方法返回一个 Future,该 Future 会在路由完成push操作时完成。

Navigator.pop

#Navigator.pop 

 Navigator.of(context).pop();
  @optionalTypeArgsvoid pop<T extends Object?>([ T? result ]) {assert(!_debugLocked);assert(() {_debugLocked = true;return true;}());final _RouteEntry entry = _history.lastWhere(_RouteEntry.isPresentPredicate);if (entry.pageBased) {if (widget.onPopPage!(entry.route, result) && entry.currentState == _RouteLifecycle.idle) {// The entry may have been disposed if the pop finishes synchronously.assert(entry.route._popCompleter.isCompleted);entry.currentState = _RouteLifecycle.pop;}entry.route.onPopInvoked(true);} else {entry.pop<T>(result);assert (entry.currentState == _RouteLifecycle.pop);}if (entry.currentState == _RouteLifecycle.pop) {_flushHistoryUpdates(rearrangeOverlay: false);}assert(entry.currentState == _RouteLifecycle.idle || entry.route._popCompleter.isCompleted);assert(() {_debugLocked = false;return true;}());_afterNavigation(entry.route);}
  • history.lastWhere:找到最后一个处于 “存在”状态 的路由条目。
  • entry.pageBased:路由是否是基于页面的。
  • widget.onPopPage:执行页面pop操作。
  • entry.route.onPopInvoked(true):通知路由pop操作被调用。
  • entry.pop<T>(result):直接调用pop。
  • _afterNavigation(entry.route):导航完成后回调。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/435449.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多处理器的概念与对比

SISD, SIMD, MISD, 和 MIMD 代表了并行计算的四种基本架构&#xff0c;它们描述了处理器如何处理指令和数据。 理解这些架构的关键在于区分指令流&#xff08;Instruction Stream&#xff09;和数据流&#xff08;Data Stream&#xff09;是单一的还是多重的。 1. SISD (Singl…

04 B-树

目录 常见的搜索结构B-树概念B-树的插入分析B-树的插入实现B树和B*树B-树的应用 1. 常见的搜索结构 种类数据格式时间复杂度顺序查找无要求O(N)二分查找有序O( l o g 2 N log_2N log2​N)二分搜索树无要求O(N)二叉平衡树无要求O( l o g 2 N log_2N log2​N)哈希无要求O(1) 以…

彩虹易支付最新版源码及安装教程(修复BUG+新增加订单投诉功能)

该系统也没版本号&#xff0c;此版本目前是比较新的版本&#xff0c;增加了订单投诉功能&#xff0c;和一个好看的二次元模板。 此版本是全开源版&#xff0c;无一处加密文件,系统默认是安装后是打不开的&#xff0c; 本站特别修复了BUG文件&#xff0c;在PHP7.4环境下也没问…

ISA-95制造业中企业和控制系统的集成的国际标准-(2)

ISA-95 文章目录 ISA-95ISA-95企业层和制造运营管理层信息模型一、企业层和制造运营管理层信息模型内容二、企业层和制造运营管理层信息模型分类 ISA-95企业层和制造运营管理层信息模型 ISA-95信息模型是指ISA-95制造业中企业和控制系统集成的国际标准定义了企业层和制造运营层…

二值图像的面积求取的两种MATLAB方法

一、引言 面积在数字图像处理中经常用到&#xff0c;在MATLAB中&#xff0c;计算二值图像的面积通常可以通过两种主要方法实现&#xff1a;遍历法和直接利用bwarea函数。下面将分别介绍这两种方法的原理和相应的MATLAB代码示例。 二、遍历法计算二值图像面积的原理和MATLAB代码…

Stable Diffusion绘画 | 来训练属于自己的模型:素材处理与打标篇

纵观整个模型训练流程&#xff0c;图片素材准备和打标环节占据的分量比重&#xff0c;绝对超过60%。 上一篇分享了图片素材准备&#xff0c;这一篇&#xff0c;开始对准备好的图片素材进行处理了。 素材处理 我已经收集了 霉霉 的25张图片&#xff1a; 但是&#xff0c;发现…

Goland 设置GOROOT报错 The selected directory is not a valid home for Go SDK

问题描述 将go版本从1.16升级到1.22时配置GoRoot报错了如下图问题 The selected directory is not a valid home for Go SDK起因的是我的这个goland比较老了&#xff0c;2020年的。所以需要设置下版本 解决 OK&#xff0c;说一下解决办法&#xff1a; 找到go的安装路径&am…

Linux之进程概念

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;Linux专栏 创作时间 &#xff1a;2024年9月28日 基本概念&#xff1a; 进程说白了其实就是一个程序的执行实例&#xff0c;正在执行的程序。 在内核层面来说&#xff0c;就是一个担当分配资源&#xff08;CPU时间…

基于大数据可视化的图书推荐及数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Unity开发绘画板——02.创建项目

1.创建Unity工程 我们创建一个名为 DrawingBoard 的工程&#xff0c;然后先把必要的工程目录都创建一下&#xff1a; 主要包含了一下几个文件夹&#xff1a; Scripts &#xff1a;存放我们的代码文件 Scenes &#xff1a;工程默认会创建的&#xff0c;存放场景文件 Shaders &…

8621 二分查找

**思路&#xff1a;** 1. 读取输入的元素个数 n。 2. 读取有序数组 ST。 3. 读取要查找的关键字 key。 4. 使用折半查找法&#xff08;即二分查找&#xff09;在数组 ST 中查找 key 的位置。 5. 如果找到 key&#xff0c;输出其位置&#xff1b;如果未找到&#xff0c;输出 &qu…

[Linux]:线程(二)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 与Windows环境不同&#xff0c;我们在linux环境下需要通过指令进行各操作&…

自然语言处理实战项目:从基础到实战

自然语言处理实战项目&#xff1a;从基础到实战 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是人工智能的重要分支&#xff0c;致力于让计算机能够理解、生成和处理人类语言。NLP 在搜索引擎、智能客服、语音助手等场景中扮演着关键角色。本文将带…

使用python进行自然语言处理的示例

程序功能 分词&#xff1a;将输入句子拆分为单词。 词性标注&#xff1a;为每个单词标注其词性。 命名实体识别&#xff1a;识别命名实体&#xff08;如人名、地名、组织等&#xff09;。 这段代码展示了如何用 nltk 进行基础的 NLP 任务&#xff0c;包括分词、词性标注和命名…

Django Web开发接口定义

Django Web 介绍 Django Web是一个Pyhton高级 Web 框架,实际上 Django 也可以做到前后端分离,即主要作为后端框架使用,不用模板渲染也是可行的。 Django Web 应用的运行流程,如下图所示: 此外,Django Web 在开发环境可以通过自带的服务器进行本地调试。但是该服务器不适…

Spring - @Import注解

文章目录 基本用法源码分析ConfigurationClassPostProcessorConfigurationClass SourceClassgetImportsprocessImports处理 ImportSelectorImportSelector 接口DeferredImportSelector 处理 ImportBeanDefinitionRegistrarImportBeanDefinitionRegistrar 接口 处理Configuratio…

从零预训练一个tiny-llama#Datawhale组队学习Task2

完整的教程请参考&#xff1a;datawhalechina/tiny-universe: 《大模型白盒子构建指南》&#xff1a;一个全手搓的Tiny-Universe (github.com) 这是Task2的学习任务 目录 Qwen-blog Tokenizer&#xff08;分词器&#xff09; Embedding&#xff08;嵌入&#xff09; RMS …

【2025】基于Django的鱼类科普网站(源码+文档+调试+答疑)

文章目录 一、基于Django的鱼类科普网站-项目介绍二、基于Django的鱼类科普网站-开发环境三、基于Django的鱼类科普网站-系统展示四、基于Django的鱼类科普网站-代码展示五、基于Django的鱼类科普网站-项目文档展示六、基于Django的鱼类科普网站-项目总结 大家可以帮忙点赞、收…

Codeforces Round 975 (Div. 2) A-C 题解

这次看到 C 题分数 1750 就开始害怕了&#xff0c;用小号打的比赛&#xff0c;一直觉得做不出来&#xff0c;最后才想到 A. Max Plus Size 题意 给你一些整数&#xff0c;选择一些涂成红色&#xff0c;两两不能相邻&#xff0c;你的得分为&#xff1a; [ 红色元素的个数 ] …

什么是 JWT?它是如何工作的?

松哥最近辅导了几个小伙伴秋招&#xff0c;有小伙伴在面小红书时遇到这个问题&#xff0c;这个问题想回答全面还是有些挑战&#xff0c;松哥结合之前的一篇旧文和大伙一起来聊聊。 一 无状态登录 1.1 什么是有状态 有状态服务&#xff0c;即服务端需要记录每次会话的客户端信…