从0到1建立前端规范

本文适合打算建立前端规范的小伙伴阅读
一、为什么需要规范

规范能给我们带来什么好处,如果没有规范会造成什么后果?这里主要拿代码规范来说。

统一代码规范的好处:

  1. 提高代码整体的可读性、可维护性、可复用性、可移植性和可靠性,这会从根本上降低开发成本,也是最重要的一点。
  2. 保证代码的一致性:软件系统中最重要的因素之一就是编码的一致性。如果编码风格一致,也更加易于维护,因为团队内任何人都可以快速理解并修改。
  3. 提升团队整体效率:开发人员通常需要花费大量的时间来解决代码质量问题,如果都按照规范编写,也有助于团队尽早发现问题,甚至完全预防问题,这将提高整个交付过程的效率。
  4. 减少code review期间一系列的争议,因为缺乏标准,在争议过程中双方很难妥协(没少因为这事争论过😕)。

若不统一代码规范,可能会造成的后果:

  1. 由于缺乏规范,导致代码风格不一,增加团队成员间的心理负担,极端情况下,某段代码只有某个人能修改(俗称屎山💩)。
  2. 团队间协作更加困难:因为开发人员得适应不同的风格,会导致效率低下(阅读代码是我们花费时间最多的地方)。
  3. 在code review期间可能经常为类似的事情做过多的讨论。
  4. 影响团队的生产力和质量,严重的甚至会影响团队和谐。

二、为什么依然有很多团队缺乏规范

在这件事上,很难达成一致是我认为最重要的原因。并且,仅仅只是拥有规范也是不够的:

  • 当开发人员被要求在短时间内完成任务时,通常会回避质量标准。
  • 团队中总是有一些有个性的人不会为了团队去改变自己的习惯。
  • 有些人在会议上就约定达成了一致,在会下依旧我行我素。

三、如何保持规范

我曾想通过会议讨论的方式来制定规范,但效果却差强人意。将失败的原因总结为大致几点:

  1. 在会议中,思维很容易发散,经常出现的情况是讨论了很多,却很难有实际性的成效,在开发中依然有不少人选择无视规则
  2. 正式的会议往往很难组织,大家很难一起有空闲的时间来讨论,一次/两周 都很困难。
  3. 会议中对实际案例分析,提出若干点优化建议后,没有对问题的优先级和侧重点进行划分,导致实际效果并不好。
  4. 还有一点也是我自己的原因,组织会议的能力有待提升…😭

经历了上述的挫败之后,经过反复复盘总结,决定换一种方式来执行:

  1. 对规范问题进行归纳分析并通过文档记录(wiki等),在团队内进行统一。
  2. 采用小步快跑的方式,有问题就解决问题,按照优先级和重要性进行排序划分,依次将问题纳入迭代,每个迭代重点解决其中几个即好。
  3. 本迭代的规范问题绝不留到下个迭代,防止堆积(当然,有时候还是得向项目经理妥协😮‍💨)。
  4. 在code review过程中严格把关,拒绝睁一只眼👀闭一只眼🧐。
  5. 当团队成员对具体某个规范有争议时,及时讨论并定出结论。
  6. 没有规则只是为了规则,制定规范的目的并不是一定要按照某某标准来执行,更多的是团队成员达成一致即可。
  7. 鼓励大家大胆的质疑规则,若不能提高代码的可读性,可维护性,可复用性,可移植性和可靠性的规则都应该被受到质疑。

四、开发者需要建立和遵守的规范

大致可以划分成这几个方向:

  • 开发流程规范
  • 代码规范
  • git commit规范
  • 项目文件结构规范
  • UI设计规范
开发流程规范

这里可能有小伙伴有疑问了,开发流程规范不是项目经理定的吗🤔️,跟我有什么关系?

这里想告诉大家的是,开发流程在一定程度上应该是由我们自己来掌控。不管是传统开发的模式还是敏捷开发的模式,对于开发者来说核心依旧是高质高效的完成用户提出的需求

笔者曾见过不少开发者在拿到产品经理的需求后就开始急匆匆的写代码,以此来体现他们的高效,但往往却因为需求理解不到位和前期代码欠缺设计导致bug率高和返工。

如何找到适合自己的开发流程是需要依靠经验来支撑的,需要反复总结和思考,最终达到高质高效完成的目的。

说一说笔者自己比较喜欢的开发流程:

在这里插入图片描述

在接收到需求后应第一时间去了解这个需求的背景是什么?这么做到底有没有解决用户的痛点?或者说用户更深层次的需求是什么?如果团队的产品经理经验不丰富,往往可以在这个阶段砍掉很多不合理的需求(这一点真的很重要)

对于复杂大功能往往还需要进行技术方案调研技术方案设计,并输出详细的设计文档。涉及到细节上,则需要将数据流走向、组件设计等通过脑图的形式呈现出来。

代码规范之格式化规范

由于每个开发者的IDE( 集成开发环境: 用于提供程序开发环境的应用程序,是集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套)不同,即使IDE相同也会因为每个人的配置不一样导致格式化的结果不一样。如何确保团队内开发人员采用统一的格式化配置呢?

这里给推荐大家使用 prettier,它内置了一套格式化的规则,具体配置:

  1. 安装依赖:
npm install --save-dev --save-exact prettier 
// or
yarn add --dev --exact prettie
  1. 创建一个空配置文件,让编辑器和其他工具知道你正在使用 Prettier:
echo {}> .prettierrc.jso
  1. 创建一个.prettierignore文件,让 Prettier CLI 和编辑器知道哪些文件不能格式化,example:
# Ignore artifacts:
dist
build
coverag
  1. 配置编辑器(VScode为例)

    IDE中安装 Prettier-Code Formater 插件:

在这里插入图片描述

找到IDE中设置模块,搜索format On Save,勾上这个就可以了。
在这里插入图片描述

现在当我们 Ctrl + S 保存代码时,插件就会帮助我们自动格式化了

这里有小伙伴要问了,要是有人将没有格式化的代码提交上去怎么办?

这时候就需要在 git commit 的阶段自动将提交的代码进行格式化,这里我们借助工具 husky,它主要可以帮助我们在 git 阶段检查提交消息、运行测试、检查代码等。没接触过的小伙伴可以去官网了解一下,配置如下:

  • 安装 husky 和 lint-staged:
 ```jsnpm install --save-dev husky lint-stagednpx husky installnpm set-script prepare "husky install"npx husky add .husky/pre-commit "npx lint-staged"// oryarn add --dev husky lint-stagednpx husky installnpm set-script prepare "husky install"npx husky add .husky/pre-commit "npx lint-staged```
  • 然后将以下内容添加到package.json中:
 ```js{"lint-staged": {"**/*": "prettier --write --ignore-unknown"}}```

​ 这段配置的意思是:当执行 git commit 阶段前,先执行lint-stagedlint-staged中的内容就是对暂存区的文件执行格式化的命令。

其他:若使用的是脚手架工具搭建的项目,会自带eslint配置(`eslintConfig`)。`prettier 和 eslint 会有一些配置上的冲突`,这个时候需要安装eslint-config-prettier 以使 ESLint 和 Prettier 相互配合,安装完后在`.eslintrc`中配置(以Create-React-App为例): 
"eslintConfig": {"extends": ["react-app","react-app/jest","prettier"]}
这样就可以用`"prettier"`的部分规则覆盖前面的规则,让它们都能正常工作。 

代码规范之JS/TS规范

JS/TS主流的大致有这几种:

  • Airbnb JavaScript Style Guide
  • Google JavaScript Style Guide
  • Idiomatic JavaScript Style Guide
  • JavaScript Standard Style Guide
  • jQuery JavaScript Style Guide

比较推荐使用 Airbnb JavaScript Style Guide,它在 Github 上足有 12万 star,几乎覆盖了 JavaScript 的每一项特性。

具体配置:

  • 安装依赖
npm install eslint --save-dev
// or
yarn add eslint --dev
  • 生成配置文件
npm init @eslint/config
// or
yarn create @eslint/config

跟着终端中的提示,按照自身需求一步步选择即可。

有了具体的规范后,我们同样需要使用工具去约束:还是通过在git commit阶段校验,若不通过则取消提交。

配置(还是在 package.json 中的 lint-staged

 "lint-staged": {"**/*": "prettier --write --ignore-unknown", //格式化"src/*": "eslint --ext .js,.ts,.tsx"  //进行eslint校验}

注意:这里如果选用的Typescript,则会默认使用@typescript-eslint/parser解析器,官方为了追求更快的解析速度,并不会对.ts文件中的类型进行检查,只会做语法检测。

如果需要对类型也进行检测,需要在extends中加上plugin:@typescript-eslint/recommended-requiring-type-checking。

索性这里换了另一种方式:在pre commit 中执行yarn run tsc,这里的意思是对项目中ts文件进行类型检测,默认会读取根目录中的tsconfig.json配置。

这种方式并不完美,它的弊端就在于全量检测,如果项目不大还好,若是项目代码量够多,检测10-20s也是常有的事。

代码规范之CSS规范

CSS检查代码规范使用 stylelint 插件,规范则推荐使用 stylelint-config-standard:

  • 安装
```js
npm install --save-dev stylelint stylelint-config-standar
```
  • 在项目的根目录中创建一个配置文件.stylelintrc.json,内容如下:
```js
{"extends": "stylelint-config-standard"
}
```
  • 解决与prettier配置的冲突:
```js
npm install --save-dev stylelint-config-prettier
```
  • 将下面配置复制到.stylelintrc.json中:

    {"extends": ["stylelint-config-standard", "stylelint-config-prettier"]
    }
    
  • 在 git commitv阶段进行检测:

```js
"lint-staged": {"**/*": "prettier --write --ignore-unknown", //格式化"src/**.{js,jsx,ts,tsx}": "eslint --ext .js,.jsx,.ts,.tsx", //对js文件检测"**/*.{less,css}": "stylelint --fix" //对css文件进行检测},
```

代码规范之自定义其他规范

下面列一些团队内定的其他规范:

  1. 命名规范

    变量的命名中应尽量减少缩写的情况发生,做到见名知意。

 ```js// 👎 自我感觉良好的缩写:let rContent = 'willen'; // 👍 无需对每个变量都写注释,从名字上就看懂let firstName = 'jackie'; // 👎 从命名无法知道返回值类型function showFriendsList() {....} // // 无法辨别函数意图,返回的是一个数组,还是一个对象,还是true or false?// 👍 明确函数意图,对于返回true or false的函数,最好以should/is/can/has开头function shouldShowFriendsList() {...}function isEmpty() {...}function canCreateDocuments() {...}function hasLicense() {...}function sendEmailToUser(user) {.... } //动词开头,函数意图就很明```
  1. 写注释

    在每个文件的顶部明确说明该组件做什么,有没有业务理解难点等等,对业务特殊函数/变量也需要写注释

 ```js/*** 导航页面-右边区域*/const Content=>()=>xxxconst MAX_INPUT_LENGTH = 8; //用于限制密码输入框function Component(props) {return (<>{/* 如果用户没有订阅则不展示广告 */}{user.subscribed ? null : <SubscriptionPlans />}</>)}```
  1. 变量兜底
 ```js// 👎 对于求值获取的变量,没有兜底const { data } = getApiRequest();data.map((s) => s.id); //没有考虑data异常的情况,代码一跑就爆炸// 👍 对于求值变量,做好兜底const { data = [] } = getApiRequest();data.map((s) => s?.id); //没有考虑data异常的情况,代码一跑就爆炸```
  1. 辅助函数必须是纯函数
 ```js// 👎 不要让功能函数的输出变化无常function plusAbc(a, b, c) {  // 这个函数的输出将变化无常,因为api返回的值一旦改变,同样输入函数的a,b,c的值,但函数返回的结果却不一定相同。var c = fetch('../api');return a+b+c;}// 👍 功能函数使用纯函数,输入一致,输出结果永远唯一function plusAbc(a, b, c) {  // 同样输入函数的a,b,c的值,但函数返回的结果永远相同。return a+b+c;}```
  1. 优先使用函数式编程
 ```js// 👎 使用for循环编程for(i = 1; i <= 10; i++) {a[i] = a[i] +1;}// 👍 使用函数式编程let b = a.map(item => ++item```
  1. 优先使用函数式组件

    除非需要用到错误边界,否则函数式组件应该是首选方法。

  2. 组件复杂度

 如果一个组件做的事情太多,应适当提取一些逻辑,将其拆分为更小的组件。如果提取的组件很复杂,则需要依照一定的规则和条件一一提取它。代码行数并不是一个客观的衡量标准,更多是需要考虑责任划分和抽象。
  1. 用错误边界

    当需要对大量数据进行渲染处理时,需要通过错误边界组件对其进行降级处理。

 ```jsfunction Component() {return (<Layout><ErrorBoundary><CardWidget /></ErrorBoundary><ErrorBoundary><FiltersWidget /></ErrorBoundary><div><ErrorBoundary><ProductList /></ErrorBoundary></div></Layout>)}```
  1. props参数传递

    props一层层传递一直是我们很头疼的一个问题,最核心的问题是不清楚props是从哪个初始组件传来的,以及props中到底有哪些东西,上下文是什么?

    因此对于传递较深的场景我推荐直接使用 context,对于 props 中的内容和上下文通过 TS 来解决。

 ```js// A.tsxinterface AProps {param: string;}const A = ({ param }: AProps) => {return <B param = {param} />;};// 👍 上下文清晰// B.tsxconst B = ({ param }: { param: AProps['param'] }) => {return <div>hello world</div>;};```
  1. props传参数量

    如果超过 5 个props,就该考虑是否拆分该组件。在某些情况下,这是需要对组件进行重构的标志。

    注意:组件使用的props越多,重新渲染的理由就越多。

  2. 避免嵌套三元运算符

    三元运算符在第一级之后变得难以阅读,虽然看起来节省了代码空间,但最好在代码中明确意图,保持良好的阅读性。

  ```js// 👎 不够清晰,要是再嵌套一层两层呢isSubscribed ? (<ArticleRecommendations />) : isRegistered ? (<SubscribeCallToAction />) : (<RegisterCallToAction />)// 👍 将判断逻辑进行拆分function CallToActionWidget({ subscribed, registered }) {if (subscribed) {return <ArticleRecommendations />}if (registered) {return <SubscribeCallToAction />}return <RegisterCallToAction />}function Component() {return (<CallToActionWidgetsubscribed={subscribed}registered={registered}/>)}```
  1. 将列表组件封装成独立组件
  ```js// 👎 列表渲染和其他逻辑杂糅在一起function Component({ topic, page, articles, onNextPage }) {return (<div><h1>{topic}</h1>{articles.map(article => (<div><h3>{article.title}</h3><p>{article.teaser}</p><img src={article.image} /></div>))}<div>You are on page {page}</div><button onClick={onNextPage}>Next</button></div>)}// 👍 将列表组件提取出来,一目了然function Component({ topic, page, articles, onNextPage }) {return (<div><h1>{topic}</h1><ArticlesList articles={articles} /><div>You are on page {page}</div><button onClick={onNextPage}>Next</button></div>)}```
  1. 避免嵌套渲染函数
  ```js// 👎 不要将其定义在渲染函数组件中function Component() {function renderHeader() {return <header>...</header>}return <div>{renderHeader()}</div>}// 👍 将其抽离到独立的组件中去import Header from '@modules/common/components/Header'function Component() {return (<div><Header /></div>)}```
  1. 组件/函数导入导出
  ```js// 👍 在文件头部导入,顺序依次为: 第三方库 > 公共组件/方法 > 非公共部分组件/方法import React from 'react'import _ from 'loadsh'import Header from '@components/header'import Content from './Content'// 👍 在底部导出export { Content, Header }export default Componen```

项目文件结构规范

在项目初期若不重视,到了后期就是到处天马行空,你很难在期望的目录下找到你想要的文件。

文件夹名称全部采用小写 + “-” 来隔开,index.ts更多是用来做导出作用,要不然最后编辑器中满屏的index.tsx,很难区分。

 - src 开发目录- pages 视图- module-a 模块A- components 私有组件- ComA.tsx- ComB.tsx- index.module.less- index.tsx- Content.tsx- module-b 模块B- components 公共组件- index.ts 导出所有组件- header- index.tsx- index.module.less- User.tsx- useGetBaseInfo.hooks.ts- routers 路由文件- store redux中的数据- utils 这里是以utils为后缀- index.ts- a.utils.ts- b.utils.ts- hooks 这里是以hooks为后缀- index.ts- a.hooks.ts- b.hooks.ts- styles 静态资源文件- service api请求,这里是以api为后缀- a.api.ts 按照后端微服务进行划分- b.api.ts- constans 常量

通过对工具函数、hooks、api 等加上后缀,更加容易区分引入的文件。

Git commit规范

git commit 规范主要可以帮助开发人员在 code review 期间更容易理解提交的内容,现在大部分主流 commit 规范都是基于Angular 团队的规范而衍生出来的,它的 message 格式如下:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer

每个提交消息都包含一个subject、一个body和一个footer (中间使用空行分割),提交信息的任何一行不能超过 100 个字符。

👉 type主要有以下几种类型:

  • feat: 一个新特性
  • fix: 修复bug
  • docs: 文档修改
  • style: 不影响代码含义的更改(空格、格式、缺少分号等)
  • refactor: 代码重构
  • perf: 优化性能
  • test: 测试用例修改
  • chore: 对构建过程或辅助工具和库的更改,例如文档生成

👉 scope:可以是影响范围的任何内容。

👉 subject:包含对更改的简洁描述,规则:

  • 使用陈述语句
  • 第一个字母不要大写
  • 末尾没有点 (.)

👉 body:commit 具体修改内容, 可以分为多行,应该包括改变的动机,并与以前的行为进行对比。

👉 footer: 一些备注, 通常是修复的 bug 的链接。

截取一张开源库的 commit,example:
在这里插入图片描述

有了规范后,我们需要通过工具去约束:commitlint。它要做的就是在我们每次提交 git commit 的时候,都会帮我们检查 commit message 是否符合一定的规范,如果不符合,就让这次提交失败。

具体配置:

# 安装 commitlint cli 和 conventional config
npm install --save-dev @commitlint/{config-conventional,cli}
# Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli配置要使用的 commitlint 规则
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js加入到husky中:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
or
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1

UI设计规范

优秀的开发者应该反向推动UI的规范,并且能够支撑UI规范的落地。

UI 规范的最大好处就是能够提质提效:

  • 在开发者的角度,与设计规范同步形成研发资产,避免重复造轮子;
  • 在测试的角度,能够避免重复的无意义走查;
  • 在UI设计师的角度,减少设计成本,提高设计效率,可以快速承接新需求;
  • 站在产品角度,提高产品迭代与优化效率,降低试错成本;
  • 站在用户角度,解决用户体验一致性。

那到底应该怎么去推动UI规范?我的做法是先让设计师去给出一系列的规范,没有相关规范就拉上产品经理一起制定规范。然后前端建立一套自己的组件库,再将组件库提供给UI设计师,以此来相互监督是否达成了规范协议。

五、总结

统一规范的最根本目的是为了保证团队成员的一致性,从而减少沟通成本,提高开发效率。

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

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

相关文章

Pytorch项目的文件结构一般都是怎么组织的?

如果是从一些比较典型的论文里弄下来的源码&#xff0c;你会发现它们的论文结构往往都非常复杂。不同的模型、不同的论文&#xff0c;可能代码结构组织的方式都不一样。但它们都不外乎就是经历这几个方面&#xff1a; 1、模型和结构模块定义&#xff1b; 2、数据集获取与处理…

Mybatis反射核心类Reflector

Reflector类负责对一个类进行反射解析&#xff0c;并将解析后的结果在属性中存储起来。 一个类反射解析后都有哪些属性呢&#xff1f;我们可以通过Reflector类定义的属性来查看 public class Reflector {// 要被反射解析的类private final Class<?> type;// 可读属性列…

带你用uniapp从零开发一个仿小米商场_6. 配置uniapp项目底部导航栏tabbar

uniapp底部tabbar介绍 在uni-app中&#xff0c;底部tabbar是一种常见的导航方式&#xff0c;它可以让用户在应用的不同页面之间进行切换。通过tabBar配置项&#xff0c;开发者可以指定一级导航栏和tab切换时显示的对应页。 在底部tabbar中&#xff0c;每个tab都有一个页面路径…

虹科分享 | AR世界揭秘:从二维码的起源到数据识别与位姿技术的奇妙融合!

引言&#xff1a;探索AR的神奇世界&#xff0c;我们将从二维码的诞生谈起。在这个科技的海洋中&#xff0c;二维码是如何帮助AR实现数据获取与位姿识别的呢&#xff1f;让我们一起揭开这层神秘的面纱&#xff01; 一、二维码的由来 二维码是将数据存储在图形中的技术&#xff…

Python | CAP - 累积精度曲线分析案例

CAP通常被称为“累积精度曲线”&#xff0c;用于分类模型的性能评估。它有助于我们理解和总结分类模型的鲁棒性。为了直观地显示这一点&#xff0c;我们在图中绘制了三条不同的曲线&#xff1a; 一个随机的曲线&#xff08;random&#xff09;通过使用随机森林分类器获得的曲线…

Gee教程1.HTTP基础

标准库启动web服务 Go语言内置了 net/http库&#xff0c;封装了HTTP网络编程的基础的接口。这个Web 框架便是基于net/http的。我们先回顾下这个库的使用。 package mainimport ("fmt""log""net/http" )func main() {//可以写成匿名函数(lambda…

【数据结构初阶】树,二叉树

树&#xff0c;二叉树 1.树概念及结构1.1树的概念1.2 树的相关概念1.3 树的表示1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构2.1概念2.2现实中的二叉树2.3 特殊的二叉树2.4 二叉树的性质2.5 二叉树的存储结构 1.树概念及结构 1.…

STM32-SPI3控制MCP3201、MCP3202(Sigma-Delta-ADC芯片)

STM32-SPI3控制MCP3201、MCP3202&#xff08;Sigma-Delta-ADC芯片&#xff09; 原理图手册说明功能方框图引脚功能数字输出编码与实值的转换分辨率设置与LSB最小和最大输出代码&#xff08;注&#xff09; 正负符号寄存器位MSB数字输出编码数据转换的LSB值 将设备输出编码转换为…

SQL JOIN 子句:合并多个表中相关行的完整指南

SQL JOIN JOIN子句用于基于它们之间的相关列合并来自两个或更多表的行。 让我们看一下“Orders”表的一部分选择&#xff1a; OrderIDCustomerIDOrderDate1030821996-09-1810309371996-09-1910310771996-09-20 然后&#xff0c;看一下“Customers”表的一部分选择&#xff…

单片机学习5——外部中断程序

#include<reg52.h>unsigned char a; sbit lcden P3^4;void main() {lcden0;EA1;EX01;IT00;a0xF0; //点亮4位小灯while(1){P1a;} }//中断服务程序 void ext0() interrupt 0 // 0 表示的是外部中断源0 {a0x0f; // 中断处理完&#xff0c;再返回主…

2018年10月4日 Go生态洞察:参与2018年Go公司问卷调查

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

系列十八、Spring bean线程安全问题

一、概述 我们知道Spring中的bean&#xff0c;默认情况下是单例的&#xff0c;那么Spring中的bean是线程安全的吗&#xff1f;这个需要分情况考虑&#xff0c;bean中是否存在成员变量&#xff1f;bean中的成员变量是怎么处理的&#xff1f;...&#xff0c;针对bean的状态会有不…

【C++】类和对象——拷贝构造和赋值运算符重载

上一篇我们讲了构造函数&#xff0c;就是对象实例化时会自动调用&#xff0c;那么&#xff0c;我们这里的拷贝构造在形式上是构造函数的一个重载&#xff0c;拷贝构造其实也是一种构造函数&#xff0c;那么我们就可以引出这里的规则 1.拷贝构造函数的函数名必须与类名相同。 2.…

数据结构——带头循环双向链表(List)

1、带头双向循环链表介绍 在上一篇博客中我们提到了链表有三个特性&#xff0c;可以组合成为8种不同类型的链表。单链表是其中比较重要的一种&#xff0c;那么这次我们选择和带头双向循环链表会会面&#xff0c;这样我们就见识过了所有三种特性的呈现。 带头双向循环链表&#…

HONOR荣耀MagicBook 15 2021款 锐龙版R5(BMH-WFQ9HN)原厂Windows11预装OEM系统含F10智能还原

链接&#xff1a;https://pan.baidu.com/s/1faYtC5BIDC2lsV_JSMI96A?pwdj302 提取码&#xff1a;j302 原厂系统Windows11.22H2工厂模式安装包,含F10一键智能还原&#xff0c;自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、荣耀 电脑管家等预装程序 …

process control 化学工程 需要用到MATLAB的Simulink功能

process control 化学工程 需要用到MATLAB的Simulink功能 所有问题需要的matlab simulink 模型 WeChat: ye1-6688 The riser tube brings in contact the recirculating catalyst with the feed oil, which then vaporizes and splits to lighter components as it flows up th…

服务器下db(数据库)的执行

1、查看 select * from xxxx&#xff08;表名&#xff09; where xxx&#xff08;列表&#xff09;1 and.......正常写就行 2、插入 如果你想要在 SELECT INSERT INTO … SELECT 语句中将部分列保持不变,只改变一两列的值,可以在 语句中直接设置目标列的值,而其他列从源表中…

【C++】类型转换 ③ ( 重新解释类型转换 reinterpret_cast | 指针类型数据转换 )

文章目录 一、重新解释类型转换 reinterpret_cast1、指针数据类型转换 - C 语言隐式类型转换报错 ( 转换失败 )2、指针数据类型转换 - C 语言显示类型强制转换 ( 转换成功 )3、指针数据类型转换 - C 静态类型转换 static_cast ( 转换失败 )4、指针数据类型转换 - C 重新解释类型…

Simulink 的代数环

代数环, 就是由于模型的输出反馈到模块或子系统先的某个输入端, 如果这个输入是直接馈入的, 那么二者在同一个采样点内需得到求解, 但又互相依赖, 哪一方都不能完成求解过程, 使得解算器无法解算导致错误产生, 这样的情况称为代数环。 一旦 Simulink 遇到代数环, 将根据 Confi…

python环境搭建-yolo代码跑通-呕心沥血制作(告别报错no module named torch)

安装软件 安装过的可以查看有没有添加环境变量 好的! 我们发车! 如果你想方便快捷的跑通大型项目,那么必须安装以下两个软件: 1.pycharm2.anaconda对应作用: pycharm:专门用来跑通python项目的软件,相当于一个编辑器,可以debug调试,可以接受远程链接调试!anaconda:专…