当前位置: 首页 > news >正文

Web学习笔记-React(组合Components)

笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课。

CONTENTS

    • 1. 创建父组件
    • 2. 从上往下传递数据
    • 3. 传递子节点
    • 4. 从下往上调用函数
    • 5. 兄弟组件间传递消息
    • 6. 无状态函数组件
    • 7. 组件的生命周期

本节内容是组件与组件之间的组合,例如用不同组件构成 DOM 树,以及给不同的组件传递数据或者调用不同组件的方法,还有不同组件的生命周期。

1. 创建父组件

我们还是继续在之前的 Box 组件上进行操作,首先创建一个 Boxes 组件,其中包含一系列 Box 组件。

components 目录中创建 boxes.jsx

import React, { Component } from 'react';class Boxes extends Component {state = {  } render() { return (<h1>Boxes</h1>);}
}export default Boxes;

然后修改一下 index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import 'bootstrap/dist/css/bootstrap.css';
import Boxes from './components/boxes';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Boxes />);

现在我们在 Boxes 中加入多个 Box,当一个组件中包含多个并列元素的时候,需要用一个标签将他们括起来,可以使用 React 中的一个虚拟标签 <React.Fragment>

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = {  } render() { return (<React.Fragment><Box /><Box /><Box /></React.Fragment>);}
}export default Boxes;

为了方便也可以用一个数组来表示,将 Box 的信息存到 state 里,由于 React 组件如果有若干个儿子那么他们的 key 需要不一样,因此还需要存一个唯一的 id

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 0},{id: 3, x: 0},{id: 4, x: 0},]} render() { return (<React.Fragment>{this.state.boxes.map(box => (<Box key={box.id} />))}</React.Fragment>);}
}export default Boxes;

2. 从上往下传递数据

通过 this.props 属性可以从上到下传递数据。例如我们在 Boxes 中传递 x

...class Boxes extends Component {state = { ...} render() { return (<React.Fragment>{this.state.boxes.map(box => (<Box key={box.id} x={box.x} name='yyj' />))}</React.Fragment>);}
}export default Boxes;

可以在 Box 中输出信息 console.log(this.props); 查看内容:

在这里插入图片描述

修改 Box 中的 x

import React, { Component } from 'react';  // 输入imrc即可补全class Box extends Component {  // 输入cc即可补全state = { x: this.props.x,};...
}export default Box;

3. 传递子节点

可以将标签写成 <Box></Box> 的形式,然后在标签中添加子标签:

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 0},{id: 3, x: 0},{id: 4, x: 0},]} render() { return (<React.Fragment>{this.state.boxes.map(box => (<Box key={box.id} x={box.x} name='yyj'><h1>Title</h1></Box>))}</React.Fragment>);}
}export default Boxes;

这样 this.props 中会多一个属性 children,可以使用 [] 单独访问某个子标签。我们可以将这个传过来的值定义在任何地方,例如可以放到每个 Box 组件的最上方:

import React, { Component } from 'react';  // 输入imrc即可补全class Box extends Component {  // 输入cc即可补全state = { x: this.props.x,};handleClickLeft = (step) => {this.setState({x: this.state.x - step});}handleClickRight = (step) => {this.setState({x: this.state.x + step});}handleClickLeftTmp = () => {this.handleClickLeft(10);}render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么console.log(this.props);return (// HTML标签中可以使用{}写一个表达式<React.Fragment>{this.props.children}<div style={this.getStyles()}>{this.state.x}</div><button onClick={this.handleClickLeftTmp} className='btn btn-primary m-2'>Left</button><button onClick={() => this.handleClickRight(10)} className='btn btn-success m-2'>Right</button></React.Fragment>);}getStyles() {...}
}export default Box;

4. 从下往上调用函数

父元素可以通过 this.props 向子元素传递信息,子元素也可以使用函数向父元素传递信息。假设我们需要实现通过点击删除按钮删除某个 Box,其信息保存在 Boxesstate 中,但是我们点击触发事件是在 Box 中(注意:每个组件的 this.state 只能在组件内部修改,不能在其他组件内修改)。

我们可以在父元素中定义好函数,然后将函数传给子元素:

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 0},{id: 3, x: 0},{id: 4, x: 0},]}handleDelete = (boxId) => {// 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来const res = this.state.boxes.filter(box => box.id !== boxId);this.setState({boxes: res});}render() { return (<React.Fragment>{this.state.boxes.map(box => (<Box key={box.id} id={box.id} x={box.x} name='yyj'onDelete={this.handleDelete}/>))}</React.Fragment>);}
}export default Boxes;

这样子元素就能调用函数对父元素进行操作了:

import React, { Component } from 'react';  // 输入imrc即可补全class Box extends Component {  // 输入cc即可补全...render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么console.log(this.props);return (// HTML标签中可以使用{}写一个表达式<React.Fragment>...<button onClick={() => this.props.onDelete(this.props.id)} className='btn btn-danger m-2'>Delete</button></React.Fragment>);}getStyles() {...}
}export default Box;

现在我们在 Boxes 中实现一个 Reset 按钮实现清空所有 Boxx

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 1},{id: 3, x: 2},{id: 4, x: 3},]}handleDelete = (boxId) => {...}handleReset = () => {const res = this.state.boxes.map(box => {return {id: box.id,x: 0,}});this.setState({boxes: res});}render() {console.log(this.state.boxes);return (<React.Fragment><buttononClick={this.handleReset}style={{marginBottom: '15px'}}className='btn btn-info'>Reset</button>{this.state.boxes.map(box => (<Box key={box.id} id={box.id} x={box.x} name='yyj'onDelete={this.handleDelete}/>))}</React.Fragment>);}
}export default Boxes;

在控制台观察时可以发现点击 Reset 按钮后 x 确实置零了,但是 Box 显示出来的 x 并没有改变,这是因为 state 值不能在外部修改,因此我们可以将 Box 中的 state 删掉,需要在该组件中渲染外面的 state 的值。

每个维护的数据仅能保存在一个 this.state 中,不要直接修改 this.state 的值,因为 setState 函数可能会将修改覆盖掉。

修改 Boxes,将之前 Box 中操作 state 的函数转移过来:

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 1},{id: 3, x: 2},{id: 4, x: 3},]}handleDelete = (boxId) => {// 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来const res = this.state.boxes.filter(box => box.id !== boxId);this.setState({boxes: res});}handleReset = () => {const res = this.state.boxes.map(box => {return {id: box.id,x: 0,}});this.setState({boxes: res});}// 需要知道修改的是哪个boxhandleClickLeft = (box) => {const boxes = [...this.state.boxes];  // 浅拷贝一份const k = boxes.indexOf(box);  // 传入的box是引用,找出其在boxes中的下标kboxes[k] = {...boxes[k]};  // 再clone一遍,相当于创建新的state,深拷贝boxes[k].x--;this.setState({boxes: boxes});}handleClickRight = (box) => {const boxes = [...this.state.boxes];const k = boxes.indexOf(box);boxes[k] = {...boxes[k]};boxes[k].x++;this.setState({boxes: boxes});}render() {return (<React.Fragment><buttononClick={this.handleReset}style={{marginBottom: '15px'}}className='btn btn-info'>Reset</button>{this.state.boxes.map(box => (<Box key={box.id} id={box.id} x={box.x} name='yyj'onDelete={this.handleDelete}onClickLeft={() => this.handleClickLeft(box)}onClickRight={() => this.handleClickRight(box)}/>))}</React.Fragment>);}
}export default Boxes;

然后修改 Box,将 this.state 替换成父组件传递过来的 props

import React, { Component } from 'react';  // 输入imrc即可补全class Box extends Component {  // 输入cc即可补全render() {  // Component类的函数,用来返回当前组件最后渲染的HTML结构是什么return (// HTML标签中可以使用{}写一个表达式<React.Fragment><div style={this.getStyles()}>{this.props.x}</div><button onClick={this.props.onClickLeft} className='btn btn-primary m-2'>Left</button><button onClick={this.props.onClickRight} className='btn btn-success m-2'>Right</button><button onClick={() => this.props.onDelete(this.props.id)} className='btn btn-danger m-2'>Delete</button></React.Fragment>);}getStyles() {let styles = {width: '50px',height: '50px',backgroundColor: 'lightblue',color: 'white',textAlign: 'center',lineHeight: '50px',borderRadius: '5px',position: 'relative',left: this.props.x};if (this.props.x === 0) {styles.backgroundColor = 'orange';}return styles;}
}export default Box;

5. 兄弟组件间传递消息

如果组件的结构关系更为复杂,那么就需要将多个组件共用的数据存放到最近公共祖先this.state 中。

我们创建一个 App 组件,其包含两个子组件 NavBar(导航栏)和 Boxes,这两个组件为兄弟组件。

首先是 navbar.jsx

import React, { Component } from 'react';class NavBar extends Component {state = {  } render() { return (<nav className="navbar bg-body-tertiary"><div className="container-fluid"><a className="navbar-brand" href="/">Navbar</a></div></nav>);}
}export default NavBar;

然后是 app.jsx

import React, { Component } from 'react';
import NavBar from './navbar';
import Boxes from './boxes';class App extends Component {state = {  } render() { return (<React.Fragment><div className='container'><NavBar /><Boxes /></div></React.Fragment>);}
}export default App;

现在假设我们要在 NavBar 中存放 Boxes 中有几个 Box 的信息,那么只能把信息放到这两个组件的最近公共祖先 App 中。

我们将 Boxes 中与 state 有关的内容都移到 App 中:

import React, { Component } from 'react';
import Box from './box';class Boxes extends Component {render() {return (<React.Fragment><buttononClick={this.props.onReset}style={{marginBottom: '15px'}}className='btn btn-info'>Reset</button>{this.props.boxes.map(box => (<Box key={box.id} id={box.id} x={box.x} name='yyj'onDelete={this.props.onDelete}onClickLeft={() => this.props.onClickLeft(box)}onClickRight={() => this.props.onClickRight(box)}/>))}</React.Fragment>);}
}export default Boxes;

移动后的 App 如下:

import React, { Component } from 'react';
import NavBar from './navbar';
import Boxes from './boxes';class App extends Component {state = { boxes: [{id: 1, x: 0},{id: 2, x: 1},{id: 3, x: 2},{id: 4, x: 3},]}handleDelete = (boxId) => {// 遍历一遍state.boxes,将box.id不为传入的参数boxId的数据保留下来const res = this.state.boxes.filter(box => box.id !== boxId);this.setState({boxes: res});}handleReset = () => {const res = this.state.boxes.map(box => {return {id: box.id,x: 0,}});this.setState({boxes: res});}// 需要知道修改的是哪个boxhandleClickLeft = (box) => {const boxes = [...this.state.boxes];  // 浅拷贝一份const k = boxes.indexOf(box);  // 传入的box是引用,找出其在boxes中的下标kboxes[k] = {...boxes[k]};  // 再clone一遍,相当于创建新的state,深拷贝boxes[k].x--;this.setState({boxes: boxes});}handleClickRight = (box) => {const boxes = [...this.state.boxes];const k = boxes.indexOf(box);boxes[k] = {...boxes[k]};boxes[k].x++;this.setState({boxes: boxes});}render() { return (<React.Fragment><div className='container'><NavBarboxesCount={this.state.boxes.length}  // 将长度传给NavBar/><Boxesboxes={this.state.boxes}onReset={this.handleReset}onClickLeft={this.handleClickLeft}onClickRight={this.handleClickRight}onDelete={this.handleDelete}/></div></React.Fragment>);}
}export default App;

现在即可在 NavBar 中读取 Boxes 的长度信息了:

import React, { Component } from 'react';class NavBar extends Component {state = {  } render() { return (<nav className="navbar bg-body-tertiary"><div className="container-fluid"><a className="navbar-brand" href="/">Navbar <span>Boxes Count: {this.props.boxesCount}</span></a></div></nav>);}
}export default NavBar;

6. 无状态函数组件

当组件中没有用到 this.state 时,可以简写为无状态的函数组件。类相对于函数最大的好处就是可以很方便地维护状态(局部变量)。

无状态函数组件(Stateless Funtion Component),输入 sfc 即可自动补全出来。函数组件相当于只有 render 函数的类组件。注意:函数的传入参数为 props 对象:

import React from 'react';const NavBar = (props) => {return (<nav className="navbar bg-body-tertiary"><div className="container-fluid"><a className="navbar-brand" href="/">Navbar <span>Boxes Count: {props.boxesCount}</span></a></div></nav>);
}export default NavBar;

7. 组件的生命周期

  • Mount 周期(挂载,表示对象被创建出来),执行顺序(按顺序执行三个函数):constructor() -> render() -> componentDidMount()
  • Update 周期(修改),执行顺序:render() -> componentDidUpdate()
  • Unmount 周期(删除),执行顺序:componentWillUnmount()

相关文章:

Web学习笔记-React(组合Components)

笔记内容转载自 AcWing 的 Web 应用课讲义&#xff0c;课程链接&#xff1a;AcWing Web 应用课。 CONTENTS 1. 创建父组件2. 从上往下传递数据3. 传递子节点4. 从下往上调用函数5. 兄弟组件间传递消息6. 无状态函数组件7. 组件的生命周期 本节内容是组件与组件之间的组合&#…...

【strstr函数的介绍和模拟实现——超详细版】

strstr函数的介绍和模拟实现 strstr函数的介绍 资源来源于cplusplus网站 strstr函数声明&#xff1a; char *strstr( const char *str1, const char *str2 ); 它的作用其实就是&#xff1a; 在字符串str1中查找是否含有字符串str2&#xff0c;如果存在&#xff0c;返回str2在…...

【Terraform】Terraform自动创建云服务器脚本

Terraform 是由 HashiCorp 创建的开源“基础架构即代码”工具 &#xff08;IaC&#xff09; 使用HCL&#xff08;配置语言&#xff09;描述云平台基础设施&#xff08;这里教你使用低级基础设施&#xff1a;交换机、云服务器、VPC、带宽&#xff09; Terraform提供者&#xf…...

TCP机制之确认应答及超时重传

TCP因为其可靠传输的特性被广泛使用,这篇博客将详细介绍一下TCP协议是如何保证它的可靠性的呢?这得主要依赖于其确认应答及超时重传机制,同时三次握手四次挥手也起到了少部分不作用,但是主要还是由确认应答和超时重传来决定的;注意:这里的可靠传输并不是说100%能把数据发送给接…...

Openharmony3.2 源码编译(ubuntu 22.04) 过程记录

OS: ubuntu 22.04 x64 1. 下载源码 1.1 安装码云repo工具 sudo apt install python3-pip git-lfsmkdir ~/bin curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o ~/bin/repo chmod ax ~/bin/repo pip3 install -i https://repo.huaweicloud.com/repository/p…...

PostgreSQL 数据库使用 psql 导入 SQL

最近我们有一个 SQL 需要导入到 PostgreSQL &#xff0c;但数据格式使用的是用&#xff1a; -- -- TOC entry 7877 (class 0 OID 21961) -- Dependencies: 904 -- Data for Name: upload_references; Type: TABLE DATA; Schema: public; Owner: - --COPY public.upload_refere…...

容器编排学习(三)端口映射与Harber镜像仓库介绍

一 对外发布服务&#xff08;端口映射&#xff09; 1 概述 新创建容器的IP 地址是随机的 容器在重启后每次 IP 都会发生变化 容器服务只有宿主机才能访问 如何才能使用容器对外提供稳定的服务? 容器端口可以与宿主机的端口进行映射绑定 从而把宿主机变成对应的服务&a…...

Day_13 > 指针进阶(2)

目录 1.函数指针数组 2.指向函数指针数组的指针 3.回调函数 qsort()函数 代码示例 void* 4.结束 今天我们在进阶指针的基础上&#xff0c;学习进阶指针的第二部分 1.函数指针数组 首先我们回顾一下指针数组 char* arr[5]://字符指针数组 - 数组 - 存放的是字符指针 in…...

对Transformer中的Attention(注意力机制)的一点点探索

摘要&#xff1a;本文试图对 Transformer 中的 Attention 机制进行一点点探索。并就 6 个问题深入展开。 ✅ NLP 研 1 选手的学习笔记 简介&#xff1a;小王&#xff0c;NPU&#xff0c;2023级&#xff0c;计算机技术 研究方向&#xff1a;文本生成、摘要生成 文章目录 一、为啥…...

车内信息安全技术-安全技术栈-软件安全

操作系统 1.隔离技术 信息安全中的隔离技术通常指的是将不同安全级别的信息或数据隔离开来,以保护敏感信息不受未授权的访问或泄露。在操作系统中,常见的隔离技术包括:虚拟化技术:通过虚拟化软件,将物理计算机分割成多个独立的虚拟计算机,每个虚拟计算机都可以运行独立的…...

Redis常见命令

命令可以查看的文档 http://doc.redisfans.com/ https://redis.io/commands/ 官方文档&#xff08;英文&#xff09; http://www.redis.cn/commands.html 中文 https://redis.com.cn/commands.html 个人推荐这个 https://try.redis.io/ redis命令在线测试工具 https://githubfa…...

Android Studio实现一笔画完小游戏

文章目录 一、项目概述二、开发环境三、详细设计3.1、数据库设计3.2、普通模式3.3、随机模式3.4、关卡列表 四、运行演示五、项目总结六、源码获取 一、项目概述 Android一笔画完是一种益智游戏&#xff0c;玩家需要从起点开始通过一条连续的线&#xff0c;将图形中所有的方块…...

【Python 程序设计】数据人员入门【02/8】

一、说明 介绍如何管理 Python 依赖项和一些虚拟环境最佳实践。 以下文章是有关 Python 数据工程系列文章的一部分&#xff0c;旨在帮助数据工程师、数据科学家、数据分析师、机器学习工程师或其他刚接触 Python 的人掌握基础知识。迄今为止&#xff0c;本初学者指南包括&#…...

学习笔记——树上哈希

普通子树哈希 树上的很多东西都是转化成链上问题的&#xff0c;比如树上哈希 树上哈希&#xff0c;主要是用于树的同构这个东西上的 什么是树的同构&#xff1f; 如图&#xff0c;不考虑节点编号&#xff0c;三棵树是同构的 将树转化成链&#xff0c;一般有两种方式&#xf…...

Opencv快速入门教程,Python计算机视觉基础

快速入门 OpenCV 是 Intel 开源计算机视觉库。它由一系列 C 函数和少量 C 类构成&#xff0c; 实现了图像处理和计算机视觉方面的很多通用算法。 OpenCV 拥有包括 300 多个 C 函数的跨平台的中、高层 API。它不依赖于其它的外部库——尽管也 可以使用某些外部库。 OpenCV 对非…...

laravel 报错误信息 Carbon\Exceptions\InvalidFormatException

Carbon\Exceptions\InvalidFormatException Unexpected data found. at vendor\nesbot\carbon\src\Carbon\Traits\Creator.php:687 683▕ return $instance; 684▕ } 685▕ 686▕ if (static::isStrictModeEnabled()) { ➜ 687…...

UI自动化之混合框架

什么是混合框架&#xff0c;混合框架就是将数据驱动与关键字驱动结合在一起&#xff0c;主要用来回归业务主流程&#xff0c;将核心流程串联起来。 上一篇我们写到了关键字驱动框架&#xff0c;关键字驱动框架是针对一个业务场景的单条测试用例的。 我们以163邮箱的登录到创建…...

SQL创建用户-非DM8.2环境(达梦数据库)

DM8:达梦数据库SQL创建用户-非DM8.2环境 环境介绍 环境介绍 在没有图形化界面&#xff0c;或者想快速创建用户&#xff0c;可以使用一下SQL语句&#xff1b;将其中的 CESHI 替换为要创建的用户名即可&#xff0c;默认创建了数据表空间&#xff0c;索引表空间&#xff0c;文件大…...

Thread类中run和start的区别

答&#xff1a;调用线程类中的 start 方法&#xff0c;才开始创建并启动线程&#xff0c;而线程被回收&#xff0c;则是要执行完线程的入口方法&#xff08;对于主线程来说&#xff0c;则是要执行完 main 方法&#xff09;&#xff0c;这里要回收线程则是要将&#xff08;&…...

ElementUI浅尝辄止35:Checkbox 多选框

一组备选项中进行多选 1.如何使用&#xff1f; 单独使用可以表示两种状态之间的切换&#xff0c;写在标签中的内容为 checkbox 按钮后的介绍。 //在el-checkbox元素中定义v-model绑定变量&#xff0c;单一的checkbox中&#xff0c;默认绑定变量的值会是Boolean&#xff0c;选…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...