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

React组件之间的通信方式总结(上)

先来几个术语:

官方我的说法对应代码
React elementReact元素let element=<span>A爆了</span>
Component组件class App extends React.Component {}
App为父元素,App1为子元素<App><App1></App1></App>

本文重点:

  • 组件有两个特性
    • 1、传入了一个“props”
    • 2、返回了一个React元素
  • 组件的构造函数
    • 如果需要重新定义constructor,必须super一下,才能激活this,也就是可以用来自React.component方法
  • 组件的props
    • 是可读的,也就是不能在组件中修改prop的属性
    • JSX中传入对象的props,可以通过{…object}的方式
  • 父子元素之间的通信(初级版本)
    • 父=>子,通过父元素的render既可改变子元素的内容。
    • 子=>夫,通过父元素传入子元素中的props上挂载的方法,让子元素触发父元素中的方法,从而进行通信。

Component

上回说到JSX的用法,这回要开讲react组件之间的一个沟通。那么什么是组件?我知道英文是Component,但这对我而言就是一个单词,毫无意义。要了解Component之间是如何进行友好交流的,那就要先了解Component是个什么鬼。

上回说到的JSX,我们可以这么创建对象:

let element=<h1 className="aaa">A爆了</h1>
//等同于
let element=React.createElement("h1",{className:"aaa"},"A爆了"
)

还是老老实实地用h1div这种标准的HTML标签元素去生成React元素。但是这样的话,我们的JS就会变得巨大无比,全部都是新建的React元素,有可能到时候我们连对象名都不晓得怎么起了,也许就变成let div1;let div2这样的。哈哈哈开个玩笑。但是分离是肯定要分离的。这个时候就有了名为Component的概念。他可以做些什么呢?简单的说就是创建一个个独立的可复用的小组件。话不多说,我们来瞅瞅来自官方的写法:

写法一:函数型创建组件,大家可以看到我就直接定义一个名为App的方法,每次执行App()的时候就会返回一个新的React元素。而这个方法我们可以称之为组件Component。有些已经上手React的朋友,可能傻了了,这是什么操作,我的高大上class呢?extend呢?很遗憾地告诉你,这也是组件,因为他符合官方定义:1、传入了一个“props” ,2、返回了一个React元素。满足上述两个条件就是Component!

function App(props) {return <span>{props.name}A爆了</span>     
}

这个是最简易的Component了,在我看来Component本身是对React.createElement的一种封装,他的render方法就相当于React.createElement的功能。高大上的组件功能来啦:

import React, { Component } from 'react';
class App extends Component {render() {return <span>{this.props.name}!A爆了</span>     }
}
export default App;

这个class版本的组件和上方纯方法的组件,从React的角度上来说,并无不同,但是!毕竟我class的方式还继承了React.Component,不多点小功能都说不过去对吧?所以说我们这么想继承了React.Component的组件的初始功能要比纯方法return的要多。所以每个React的Component我们都可以当作React元素直接使用。

好了,我们来研究研究Component这个类的方法吧。

首先是一个神奇的constructor函数,这个函数在类中,可以说是用于初始化的函数。如果省去不写,也不会出错,因为我们的组件都是React.Component的子类,所以都继承了React.Componentconstructor方法。如果我们在子类Component中定义了constructor相当于是覆盖了父类的方法,这样React.Component的构造函数就失效了。简单地来说就是很多默认的赋值都失效了。你是获取不到props的。因此官方为了提醒大家不要忘记super一下,也就是继承父类的constructor,因此会报"this hasn't been initialised - super() hasn't been called"这个错误。意思就是你先继承一下。也就是说super是执行了父类的constructor的方法。所以!!!重点来了——我们写super的时候不能忘记传入props。不传入props,程序就无法获取定义的组件属性了。

constructor(props) {super(props);//相当于React.Component.call(this,props)
}

官方也给大家划重点了:

Class components should always call the base constructor with props.(类组建在执行基本constructor的时候,必须和props一起。)

对于我们没有写constructor,但在其他自带方法中,比如render,也可以直接获取到props,这个诡异的操作就可以解释了。因为我们省略了重定义,但是constructor本身不仅是存在的而且也执行了,只不过没有在我们写的子类中体现出来而已。

props的坑

分析了Component之后,大家有没有发现Component的一个局限?没错!就是传参!关于Component的一个定义就是,只能传入props的参数。也就是说所有的沟通都要在这个props中进行。有种探监的既视感,只能在规定的窗口,拿着对讲机聊天,其他的方式无法沟通。React对于props有着苛刻的规定。参考 前端进阶面试题详细解答

All React components must act like pure functions with respect to their props.

简单地来说就是props是不能被改变的,是只读的。(大家如果不信邪,要试试,可以直接改props的值,最终等待你的一定是报错页面。)

这里需要科普下纯函数pure function的概念,之后Redux也会遇到的。意思就是纯函数只是一个过程,期间不改变任何对象的值。因为JS的对象有个很奇怪的现象。如果你传入一个对象到这个方法中,并且改变了他某属性的值,那么传入的这个对象在函数外也会改变。pure function就是你的改动不能对函数作用域外的对象产生影响。所以每次我们在Component里面会遇到一个新的对象state,一般这个组件的数据我们会通过state在当前组件中进行变化处理。

划重点:因为JS的特性,所以props设置为只读,是为了不污染全局的作用域。这样很大程度上保证了Component的独立性。相当于一个Component就是一个小世界。

我发现定义props的值也是一门学问,也挺容易踩坑的。

比如下方代码,我认为打印出来应该是props:{firstName:"Nana",lastName:"Sun"...},结果是props:{globalData:true}.

let globalData={firstName:"Nana",lastName:"Sun",greeting:["Good moring","Good afternoon","Good night"]
}
ReactDOM.render(<App globalData/>, document.getElementById('root'));

所以对于props是如何传入组件的,我觉得有必要研究一下下。

props其实就是一个参数直接传入组件之中的,并未做什么特殊处理。所以对props进行处理的是在React.createElement这一个步骤之中。我们来回顾下React.createElement是怎么操作的。

React.createElement("yourTagName",{className:"aaa",color:"red:},  "文字/子节点")//对应的JSX写法是:<yourTagName className="aaa" color="red>文字/子节点</yourTagName>

也就是他的语法是一个属性名=属性值,如果我们直接放一个<App globalData/>,那么就会被解析成<App globalData=true/>},所以props当然得不到我们想要的结果。这个是他的一个语法,我们无法扭转,但是我们可以换一种写法,让他无法解析成属性名=属性值,这个写法就是{...globalData},解构然后重构,这样就可以啦。

Components之间的消息传递

单个组件的更新->setState

Components之间的消息传递是一个互动的过程,也就是说Component是“动态”的而不是“静态”的。所以首先我们得让静态的Component“动起来”,也就是更新组件的的值,前面不是提过props不能改嘛,那怎么改?前文提过Component就是一个小世界,所以这个世界有一个状态叫做state

先考虑如何外力改变Component的状态,就比如点击啦,划过啦。

class App extends Component {state={num:0}addNum=()=>{this.setState({num:this.state.num+1})}render() {return( [<p>{this.state.num}</p>,<button onClick={this.addNum}>点我+1</button>])     }
}

这里我用了onClick的用户主动操作的方式,迫使组件更新了。其实component这个小世界主要就是靠state来更新,但是不会直接this.state.XXX=xxx直接改变值,而是通过this.setState({...})来改变。

这里有一个小tips,我感觉大家很容易犯错的地方,有关箭头函数的this指向问题,大家看下图。箭头函数转化成ES5的话,我们就可以很清晰得看到,箭头函数指向他上一层的函数对象。这里也就指向App这个对象。

如果不想用箭头函数,那么就要注意了,我们可以在onClick中加一个bind(this)来绑定this的指向,就像这样onClick={this.addNum.bind(this)}

  render() {return( [<p>{this.state.num}</p>,<button onClick={this.addNum.bind(this)}>点我+1</button>])     }

组件之间的通信

那么Component通过this.setState可以自high了,那么组件之间的呢?Component不可能封闭自己,不和其他的Component合作啊?那我们可以尝试一种方式。

在App中我把<p>{this.state.num}</p>提取出来,放到App1中,然后App1直接用props来显示,因为props是来自父元素的。相当于我直接在App(父元素)中传递num给了App1(子元素)。每次App中state发生变化,那么App1就接收到召唤从而一起更新。那么这个召唤是基于一个什么样的理论呢?这个时候我就要引入React的生命周期life cycle的问题了。

//App
render() {return( [<App1 num={this.state.num}/>,<button onClick={this.addNum}>点我+1</button>])     
}
//App1
render() {return( [<p>{this.props.num}</p>,])     
}

react的生命周期

看到生命周期life cycle,我就感觉到了生生不息的循环cycle啊!我是要交代在这个圈圈里了吗?react中的生命周期是干嘛的呢?如果只是单纯的渲染就没有生命周期一说了吧,毕竟只要把内容渲染出来,任务就完成了。所以这里的生命周期一定和变化有关,有变化才需要重新渲染,然后再变化,再渲染,这才是一个圈嘛,这才是life cycle。那么React中的元素变化是怎么变的呢?

先来一个官方的生命周期(我看着就头晕):

点我看live版本

官方的全周期:

官方的简约版周期:

有没有看着头疼,反正我是跪了,真令人头大的生命周期啊。我还是通过实战来确认这个更新是怎么产生的吧。实战出真理!(一些不安全的方法,或者一些我们不太用得到的,这里就不讨论了。)

Mounting装备阶段:

  • constructor()
  • render()
  • componentDidMount()

Updating更新阶段:

  • render()
  • componentDidUpdate()
  • 具有争议的componentWillReceiveProps()

Unmounting卸载阶段:

  • componentWillUnmount()

Error Handling错误捕获极端

  • componentDidCatch()

这里我们通过运行代码来确认生命周期,这里是一个父元素嵌套子元素的部分代码,就是告诉大家,我在每个阶段打印了啥。这部分的例子我用的还是上方的App和App1的例子。

//father
constructor(props){console.log("father-constructor");
}
componentDidMount() {console.log("father-componentDidMount");
}
componentWillUnmount() {console.log("father-componentWillUnmount");
}
componentDidUpdate() {console.log("father-componentDidUpdate");
}
render() {console.log("father-render");
}
//child
constructor(props){console.log("child-constructor");super(props)
}
componentDidMount() {console.log("child-componentDidMount");
}
componentWillUnmount() {console.log("child-componentWillUnmount");
}
componentDidUpdate() {console.log("child-componentDidUpdate");
}
componentWillReceiveProps(){console.log("child-componentWillReceiveProps");
}
render() {console.log("child-render");
}

好了开始看图推理

初始化运行状态:

父元素先运行创建这没有什么问题,但是问题是父元素还没有运行结束,杀出了一个子元素。也就是说父元素在render的时候里面碰到了子元素,就先装载子元素,等子元素装载完成后,再告诉父元素我装载完毕,父元素再继续装载直至结束。

我点击了一下,父元素setState,然后更新了子元素的props

同样的先父元素render,遇到子元素就先暂时挂起。子元素这个时候出现了componentWillReceiveProps,也就是说他是先知道了父元素传props过来了,然后再render。因为有时候我们需要在获取到父元素改变的props之后再执行某种操作,所以componentWillReceiveProps很有用,不然子元素就直接render了。突想皮一下,那么我子元素里面没有props那是不是就不会执行componentWillReceiveProps了??就是<App1 num={this.state.num}/>变成<App1/>。我还是太天真了。这个componentWillReceiveProps依然会执行也就是说:

componentWillReceiveProps并不是父元素传入的props发生了改变,而是父元素render了,就会出发子元素的这个方法。

关于卸载,我们来玩一下,把App的方法改成如下方所示,当num等于2的时候,不显示App1。

render() {return( <div>{this.state.num===2?"":<App1 num={this.state.num}/>}      <button onClick={this.addNum}>点我+1</button></div>)     
}

App先render,然后卸载了App1之后,完成了更新componentDidUpdate

那么大家看懂了生命周期了吗??我总结了下:

  • 父元素装载时render了子元素,就先装载子元素,再继续装载父元素。
  • 父元素render的时候,子元素就会触发componentWillReceiveProps,并且跟着render
  • 父元素卸载子元素时,先render,然后卸载了子元素,最后componentDidUpdate

如何子传父亲呢??

通过生命周期,子元素可以很容易的获取到父元素的内容,但是父元素如何获得来自子元素的内容呢?我们不要忘记了他们为一个沟通桥梁props!我们可以在父元素中创建一个方法用于获取子元素的信息,然后绑定到子元素上,然后不就可以获取到了!操作如下所示:

receiveFormChild=(value)=>{console.log(value)
}
render() {return( <div>{this.state.num===2?"":<App1 num={this.state.num} popToFather={this.receiveFormChild}/>}      <button onClick={this.addNum}>点我+1</button></div>)     
}

当子元素运行popToFather的时候,消息就可以传给父亲啦!

子元素:

render() {return( [<p>{this.props.num}</p>,<button onClick={()=>this.props.receiveState("来自子元素的慰问")}>子传父</button>])     
}

父元素成功获取来自子元素的慰问!

这次就科普到这里吧。

相关文章:

React组件之间的通信方式总结(上)

先来几个术语&#xff1a; 官方我的说法对应代码React elementReact元素let element<span>A爆了</span>Component组件class App extends React.Component {}无App为父元素&#xff0c;App1为子元素<App><App1></App1></App> 本文重点&…...

C++17 nodiscard标记符

文章目录前言弃值表达式nodiscard标记符函数非弃值声明类/枚举类/结构 非弃值声明返回类引用与类指针前言 在C 17中引入了一个标记符nodiscard&#xff0c;用于声明一个 “非弃值(no-discard)表达式”。那么在开始之前&#xff0c;我们需要了解一下什么是弃值表达式。 弃值表…...

SAP 寄售业务的标准流程

SAP的标准寄售业务&#xff0c;供应商提供的物料只有在公司使用之后才需支付应付账款&#xff0c;类似是一种先吃后付钱的餐饮流程。 SAP的寄售流程把实际业务中的供应商&#xff0c;采购方收货&#xff0c;采购方消耗物料&#xff0c;采购方依据消耗物料数量进行付款&#xff…...

操作系统高频知识

目录 一、线程与进程的区别 区别&#xff1a; 二、多进程和多线程区别 三、进程与程序的区别 三、死锁 1、是什么 2、产生的原因 3、产生的必要条件&#xff08;4个&#xff09; 4、如何预防 5、如何避免 6、如何检测 7、如何解除 一、线程与进程的区别 1、线程&a…...

加载预训练模型,模型微调,在自己的数据集上快速出效果

针对于某个任务&#xff0c;自己的训练数据不多&#xff0c;先找到一个同类的别人训练好的模型&#xff0c;把别人现成的训练好了的模型拿过来&#xff0c;换成自己的数据&#xff0c;调整一下参数&#xff0c;再训练一遍&#xff0c;这就是微调&#xff08;fine-tune&#xff…...

VScode远程连接服务器-过程试图写入的管道不存在-could not establist connection to【已解决】

问题描述 使用服务器的过程中突然与服务器断连&#xff0c;报错如下&#xff1a;could not establist connection to [20:23:39.487] > ssh: connect to host 10.201.0.131 port 22: Connection timed out > [20:23:39.495] > 过程试图写入的管道不存在。 > [20…...

电子技术——B类输出阶

电子技术——B类输出阶 下图展示了一个B类输出阶的原理图&#xff0c;B类输出阶由两个互补的BJT组成&#xff0c;不同时导通。 原理 当输入电压 vI0v_I 0vI​0 的时候&#xff0c;两个晶体管都截止输出电压为零。当 vIv_IvI​ 上升至超过0.5V的时候&#xff0c;此时 QNQ_NQN…...

【老卫搬砖】034期:HarmonyOS 3.1 Beta 1初体验,我在本地模拟器里面刷短视频

今天啊打开这个DevEco Studio的话&#xff0c;已经提示有3.1Beta1版本的一个更新啊。然后看一下它的一些特性。本文也演示了如何在本地模拟器里面运行HarmonyOS版短视频。 主要特性 新特性包括&#xff1a; Added support for Windows 11 64-bit and macOS 13.x OSs, as well…...

Day901.内部临时表 -MySQL实战

内部临时表 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于内部临时表的内容。 sort buffer、内存临时表和 join buffer。这三个数据结构都是用来存放语句执行过程中的中间数据&#xff0c;以辅助 SQL 语句的执行的。 其中&#xff0c;在排序的时候用到了 sort bu…...

jstatd的启动方式与关闭方式

启动方式与注意事项&#xff1a; 启动方式&#xff1a; 前台启动不打印日志&#xff1a; jstatd -J-Djava.security.policyjstatd.all.policy -J-Djava.rmi.server.hostname服务器IP 前台启动并打印日志&#xff1a; ./jstatd -J-Djava.security.policyjstatd.all.policy -…...

_improve-3

createElement过程 React.createElement()&#xff1a; 根据指定的第一个参数创建一个React元素 React.createElement(type,[props],[...children] )第一个参数是必填&#xff0c;传入的是似HTML标签名称&#xff0c;eg: ul, li第二个参数是选填&#xff0c;表示的是属性&#…...

C++——异常

目录 C语言传统的处理错误的方式 C异常概念 异常的使用 异常的抛出和匹配原则 在函数调用链中异常栈展开匹配原则 自定义异常体系 异常的重新抛出 ​编辑 异常安全 异常规范 C标准库的异常体系 异常的优缺点 C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; …...

MVVM 架构进阶:MVI 架构详解

前言Android开发发展到今天已经相当成熟了&#xff0c;各种架构大家也都耳熟能详&#xff0c;如MVC,MVP,MVVM等&#xff0c;其中MVVM更是被官方推荐&#xff0c;成为Android开发中的显学。不过软件开发中没有银弹&#xff0c;MVVM架构也不是尽善尽美的&#xff0c;在使用过程中…...

有没有必要考PMP证书?

其实针对有没有必要考试吗&#xff0c;这个可以根本不同行业的人来决定的。 1.高等教育项目管理专业科班出身的人员。 在我国本科学历和硕士研究生学历中&#xff0c;项目管理也有开设。不管以后从事的工作是否为项目管理或其他管理&#xff0c;作为本专业的同学&#xff0c;…...

1 机器学习基础

1 机器学习概述 1.1 数据驱动的问题求解 大数据-Big Data 大数据的多面性 1.2 数据分析 机器学习&#xff1a;海量的数据&#xff0c;获取有用的信息 专门研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识结构使之…...

java基础系列(六) sleep()和wait() 区别

一.前言 关于并发编程这块, 线程的一些基础知识我们得搞明白, 本篇文章来说一下这两个方法的区别,对Android中的HandlerThread机制原理可以有更深的理解, HandlerThread源码理解,请查看笔者的这篇博客: HandlerThread源码理解_handlerthread 源码_broadview_java的博客-CSDN博…...

Urho3D序列化

从Serializable派生的类可以通过定义属性将其自动序列化为二进制或XML格式。属性存储到每个类的上下文中。场景加载/保存和网络复制都是通过从Serializable派生Node和Component类来实现的。 支持的属性类型是Variant支持的所有属性类型&#xff0c;不包括指针和自定义值。 属性…...

企业级信息系统开发学习1.3——利用注解配置取代Spring配置文件

文章目录一、利用注解配置类取代Spring配置文件&#xff08;一&#xff09;打开项目&#xff08;二&#xff09;创建新包&#xff08;三&#xff09;拷贝类与接口&#xff08;四&#xff09;创建注解配置类&#xff08;五&#xff09;创建测试类&#xff08;六&#xff09;运行…...

VUE DIFF算法之快速DIFF

VUE DIFF算法系列讲解 VUE 简单DIFF算法 VUE 双端DIFF算法 文章目录VUE DIFF算法系列讲解前言一、快速DIFF的代码实现二、实践练习1练习2总结前言 本节我们来写一下VUE3中新的DIFF算法-快速DIFF&#xff0c;顾名思义&#xff0c;也就是目前最快的DIFF算法&#xff08;在VUE中&…...

一文掌握如何轻松稿定项目风险管理【静说】

风险管理对于每个项目经理和PMO都非常重要&#xff0c;如果管理不当会出现很多问题&#xff0c;咱们以前分享过很多风险管理的内容&#xff1a; 风险无处不在&#xff0c;一旦发生&#xff0c;会对一个或多个项目目标产生积极或消极影响的确定事件或条件。那么接下来介绍下五大…...

操作系统权限提升(十四)之绕过UAC提权-基于白名单AutoElevate绕过UAC提权

系列文章 操作系统权限提升(十二)之绕过UAC提权-Windows UAC概述 操作系统权限提升(十三)之绕过UAC提权-MSF和CS绕过UAC提权 注&#xff1a;阅读本编文章前&#xff0c;请先阅读系列文章&#xff0c;以免造成看不懂的情况&#xff01;&#xff01; 基于白名单AutoElevate绕过…...

ecology9-谷歌浏览器下-pdf.js在渲染时部分发票丢失文字 问题定位及解决

问题 问题描述 &#xff1a; 在谷歌浏览器下&#xff0c;pdf.js在渲染时部分发票丢失文字&#xff1b;360浏览器兼容模式不存在此问题 排查思路&#xff1a;1、对比谷歌浏览器的css样式和360浏览器兼容模式下的样式&#xff0c;没有发现关键差别 2、✔使用Fiddler修改网页js D…...

JavaScript Window Navigator

文章目录JavaScript Window NavigatorWindow Navigator警告!!!浏览器检测JavaScript Window Navigator window.navigator 对象包含有关访问者浏览器的信息。 Window Navigator window.navigator 对象在编写时可不使用 window 这个前缀。 实例 <div id"example"…...

Linux基础命令-du查看文件的大小

文章目录 du 命令介绍 语法格式 基本参数 参考实例 1&#xff09;以人类可读形式显示指定的文件大小 2&#xff09;显示当前目录下所有文件大小 3&#xff09;只显示目录的大小 4&#xff09;显示根下哪个目录文件最大 5&#xff09;显示所有文件的大小 6&#xff0…...

文献计量分析方法:Citespace安装教程

Citespace是一款由陈超美教授开发的可用于海量文献可视化分析的软件&#xff0c;可对Web of Science&#xff0c;Scopus&#xff0c;Pubmed&#xff0c;CNKI等数据库的海量文献进行主题、关键词&#xff0c;作者单位、合作网络&#xff0c;期刊、发表时间&#xff0c;文献被引等…...

MVI 架构更佳实践:支持 LiveData 属性监听

前言MVI架构为了解决MVVM在逻辑复杂时需要写多个LiveData(可变不可变)的问题,使用ViewState对State集中管理&#xff0c;只需要订阅一个 ViewState 便可获取页面的所有状态通过集中管理ViewState&#xff0c;只需对外暴露一个LiveData&#xff0c;解决了MVVM模式下LiveData膨胀…...

LeetCode438 找到字符串中所有字母异位词 带输入和输出

题目&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s “cbaebabacd”, …...

ACSC 2023 比赛复现

Admin Dashboard 在 index.php 中可以看到需要访问者是 admin 权限&#xff0c;才可以看到 flag。 report.php 中可以让 admin bot 访问我们输入的 url&#xff0c;那么也就是说可以访问 addadmin.php 添加用户。 在 addadmin.php 中可以添加 admin 用户&#xff0c;但是需…...

【Linux驱动开发100问】什么是模块?如何编写和使用模块?

&#x1f947;今日学习目标&#xff1a;什么是Linux内核&#xff1f; &#x1f935;‍♂️ 创作者&#xff1a;JamesBin ⏰预计时间&#xff1a;10分钟 &#x1f389;个人主页&#xff1a;嵌入式悦翔园个人主页 &#x1f341;专栏介绍&#xff1a;Linux驱动开发100问 什么是模块…...

Android 9.0 Recent列表不显示某个app

1.概述 在9.0的系统产品rom定制化开发中,在一些产品定制化需求中,也是有很多重要的功能实现的,比如在某些app的开发中 由于不想被杀掉,所以就不想出现在recent的列表中,因此就需要从recent的列表中,去掉这个app的显示,然后这里有 两种方法实现这个功能,一种是在app中就…...

网站如何做广告/济南seo怎么优化

Linux内核设计与实现&#xff08;6&#xff09;第六章&#xff1a;内核数据结构1.链表1.1 container_of 解释2. 队列3. 映射4. 红黑树1.链表 内核中关于链表定义的代码位于&#xff1a; include/linux/list.h linux内核中的链表使用方法和一般数据结构中定义的链表是有所不同的…...

wordpress自定义登录页/关键词排名怎么上首页

tar格式&#xff0c;会打包成一个文件&#xff0c;可以对多个目录&#xff0c;或者多个文件进行打包 tar命令只是打包&#xff0c;不会压缩&#xff0c;打包前后大小是一样的 tar命令 -c //打包 -x //解压 -f //指定文件 -t //查看 tar cf 压缩后的文件名 要…...

怎么用vs做网站开发/深圳网络营销外包公司推荐

VirtualAlloc 分配的内存是以 4K 为最小单位、连续的内存地址(但映射到真实的内存时它不一定是连续的), 前面说了, 它不适合分配小内存(譬如只有几个字节的变量); 局部的变量在 "栈" 中有程序自动管理, 那么那些全局的小变量怎么办呢? 这就要用到 "堆".这…...

企业如何推广网站/免费创建网站平台

LeetCode 637. 二叉树的层平均值 难度 简单 给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。 示例 输入&#xff1a;3/ \9 20/ \15 7 输出&#xff1a;[3, 14.5, 11] 解释&#xff1a; 第 0 层的平均值是 3 , 第1层是 14.5 , 第2层是 11 。因此返回 [3, 1…...

search everything wordpress/长尾关键词挖掘

将企业软件中进行数据交换的业务对象&#xff0c;例如客户、订单或产品等常规模型进行标准化&#xff0c;让它们包含所有属性与关联信息&#xff0c;这种做法看上去似乎是一种吸引人的目标&#xff0c;但在Stefan Tilkov看来&#xff0c;这种方式将产生标准数据模型&#xff08…...

wordpress怎么加统计代码/seo综合查询是什么意思

EDUSOHO踩坑笔记之二十四&#xff1a;缓存Redis Reids 即可当做数据库使用&#xff0c;也可当做缓存使用。启用 Redis 服务&#xff0c;需安装PHPRedis 扩展。框架集成了 Redis 服务&#xff0c;可通过以下方式启用&#xff1a; $biz->register(new Biz\Frameowrk\Provider…...