阿赵的MaxScript学习笔记分享十四《Struct结构体的使用和面向对象的思考》

news2024/12/25 16:52:34

MaxScript学习笔记目录

大家好,我是阿赵
之前写了一些MaxScript的学习笔记,里面实现的功能不算很复杂,所以都是使用了偏向于面向过程的方式去编写的。
我本人其实是比较习惯用面向对象的方式去编写代码。关于面向过程和面向对象之间的优缺点对比,各位如果不是很熟悉的话,有空可以去自行查询了解一下。按我自己的理解简单概括一下:
1、面向过程运行的效率高,但如果代码逻辑复杂的时候,修改和维护的难度会比较大
2、面向对象性能较差,内存也占用得比较多,但它易于管理和维护,扩展性好
在编写MaxScript的时候,可以用Struct结构体来部分实现面向对象,下面来介绍一下。

一、Struct的基础使用

1、例子:

在说理论之前,先看一个简单的例子:

(
local TestPerson
local PrintPerson
struct person (name,age,sex,height = 175)

fn TestPerson = 
(
	
	local Tom = person()
	Tom.name = "Tom"
	Tom.age = 23
	Tom.sex = "male"
	Tom.height = 180	
	PrintPerson Tom
	
	local Bill = person name:"Bill" age:19 sex:"male"
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = "";
	content +=("name:"+ obj.name+"\n")
	content +=("age:"+ (obj.age as string) + "\n")
	content += ("sex:"+obj.sex+ "\n")
	content += ("height:"+(obj.height as string)+"\n")
	print content
	return "ok"
)

TestPerson()

)

运行代码,可以看到打印输出:

"name:Tom
age:23
sex:male
height:180
"
"name:Bill
age:19
sex:male
height:175
"
"ok"

2、Struct的创建和属性使用

从上面的例子可以看出,我定义了一个叫做person的结构体。这个person结构体里面有以下几个属性:name、age、sex、height,其中height是有默认值175的
从单词的意思上就可以知道,这是一个人物信息的结构体,它包含了名字、年龄、性别、身高这4个属性。
接下来使用person结构体来创建对象。
从上面的例子里面可以看出,有2种方式可以创建对象

1.创建一个空的person

local Tom = person()
	Tom.name = "Tom"
	Tom.age = 23
	Tom.sex = "male"
	Tom.height = 180	

用struct名称加括号,可以创建出这个struct的对象。
然后可以在对象后面接”.属性名称”,来给对象身上的属性赋值。

2.创建的时候指定参数

local Bill = person name:"Bill" age:19 sex:"male"

在创建的时候,也可以直接用属性的”名称:值”的方式直接赋值给属性。

3、Struct内部定义方法

除了简单的指定一些变量属性,Struct还可以写函数在里面,然后从外部调用函数。
把上面的例子稍作修改,变成这样:

(
local TestPerson
local PrintPerson
struct person (
	name,
	age,
	sex,
	height = 175,
	fn GetPersonInfoString = 
	(
		local content = "";
		content +=("name:"+ this.name+"\n")
		content +=("age:"+ (this.age as string) + "\n")
		content += ("sex:"+this.sex+ "\n")
		content += ("height:"+(this.height as string)+"\n")
	)
)

fn TestPerson = 
(
	
	local Tom = person()
	Tom.name = "Tom"
	Tom.age = 23
	Tom.sex = "male"
	Tom.height = 180	
	PrintPerson Tom
	
	local Bill = person name:"Bill" age:19 sex:"male"
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()

)

运行脚本,会发现结果和之前是一样的。
这里我在person这个结构体里面定义了一个叫做GetPersonInfoString的函数,然后把自身的信息往外返回,在打印信息的时候,只需要向person对象调用GetPersonInfoString函数,就得到了需要打印的结果了。

4、注意事项

1.struct内部的变量和函数的分隔

从上面的例子可以看出,struct的变量和函数,都必须用逗号分割。特别是函数,很容易漏掉。不过在最后一个变量或者函数后,就不能再加逗号了。

2.struct的变量和方法命名

(1)struct内部调用外部变量

来看一段例子:

(
local TestPerson
local PrintPerson
local testVal = 1
struct person (
	name,
	age,
	sex,
	height = 175,
	fn GetPersonInfoString = 
	(
		testVal = testVal +1
		local content = testVal as string
		return content
	)
)

fn TestPerson = 
(	
	local Tom = person()
	Tom.name = "Tom"
	Tom.age = 23
	Tom.sex = "male"
	Tom.height = 180	
	PrintPerson Tom
	
	local Bill = person name:"Bill" age:19 sex:"male"
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()

)

这段例子是从上面的例子改的,需要注意的地方是,我在struct外部定义了一个局部变量testVal = 1,然后在struct内部使用这个testVal并对其进行赋值。
运行脚本,会发现打印如下:

"2"
"3"
"ok"

可以看出,在struct内部是可以调用外部的变量的。

(2)struct内部变量和外部变量重名

再对这个例子进行小修改:

(
local TestPerson
local PrintPerson
local height = 1
struct person (
	name,
	age,
	sex,
	height = 175,
	fn GetPersonInfoString = 
	(
		height = height +1
		local content = height as string
		return content
	)
)

fn TestPerson = 
(	
	local Tom = person()
	Tom.name = "Tom"
	Tom.age = 23
	Tom.sex = "male"
	Tom.height = 180	
	PrintPerson Tom
	
	local Bill = person name:"Bill" age:19 sex:"male"
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()
print ("height:"+(height as string))
)

这次我把testVal改名了,改成和Struct里面的height变量重名了。
运行脚本,可以看到:

"181"
"176"
"height:1"

从这里我们可以看出来,如果Struct的变量和外部重名了,在使用的时候,会使用内部的变量。

3.内部参数问题

再对例子做小修改:

(
local TestPerson
local PrintPerson
local height = 1
struct person (
	name,
	age,
	sex,
	height = 175,
	fn GetPersonInfoString = 
	(
		height = height +1
		local content = height as string
		return content
	),	
	fn SetHeight height = 
	(
		height = height
	)
)

fn TestPerson = 
(	
	
	local Bill = person name:"Bill" age:19 sex:"male"
	Bill.SetHeight 200
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()
print ("height:"+(height as string))
)

这次,我加了一个SetHeight 函数在struct里面,传进去一个height的变量,然后很莫名其妙的height = height,因为height这个名字出现在了3个地方,首先是struct外部的变量,然后是struct本身的变量,最后是函数的传入变量,那么这个height究竟是代表了哪个?
看看打印结果

"176"
"height:1"

可以看出,struct内部的height变量并没有收到height = height的影响,struct外部的height变量也没有受到height = height的影响,这里赋值的只是函数传进去的height参数。
再进行一下修改:

(
local TestPerson
local PrintPerson
local height = 1
struct person (
	name,
	age,
	sex,
	height = 175,
	fn GetPersonInfoString = 
	(
		height = height +1
		local content = height as string
		return content
	),	
	fn SetHeight height = 
	(
		this.height = height
	)
)

fn TestPerson = 
(	
	
	local Bill = person name:"Bill" age:19 sex:"male"
	Bill.SetHeight 200
	PrintPerson Bill
)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()
print ("height:"+(height as string))
)

这次把SetHeight 函数的内容改成了

this.height = height

这次的输出结果是:

"201"
"height:1"

可以看出,struct的height被赋值了。

4.公共和私有变量函数

对上面的例子再做修改:

(
local TestPerson
local PrintPerson
struct person (
	name,
	age,
	sex,
	height = 175,
	
	fn GetPersonInfoString = 
	(
		return (this.GetWeightStr())
	),	

	fn SetWeight val = 
	(
		this.weight = val
	),
	private weight = 1,
	private fn GetWeightStr = 
	(
		local content = this.weight as string
		return content
	)
)

fn TestPerson = 
(	
	
	local Bill = person name:"Bill" age:19 sex:"male"
	Bill.SetWeight 100
	
	PrintPerson Bill

)

fn PrintPerson obj = 
(
	local content = obj.GetPersonInfoString()
	print content
	return "ok"
)

TestPerson()
)

可以看到在struct里面,多了一个私有的变量weight,还有一个私有的函数GetWeightStr。
这样写是允许的,这个weight变量和GetWeightStr方法,是只有struct内部才能使用,如果在外部调用,就会报错。
还有一点值得注意的是,在struct里面,可以用一个public或者private定义一列连续的变量或者函数
于是我们可以把struct内部的代码改成这样:

struct person (
	public
	name,
	age,
	sex,
	height = 175,
	
	fn GetPersonInfoString = 
	(
		return (this.GetWeightStr())
	),	
	fn SetWeight val = 
	(
		this.weight = val
	),
	private 
	weight = 1,
	fn GetWeightStr = 
	(
		local content = this.weight as string
		return content
	)
)

在public下面的一段变量和函数,都是公共的,在private下面的一段变量和函数,都是私有的。
public和private没有严格的顺序和数量,可以先private后public也行,或者先private再public再private都可以。

5.总结

说了这么多废话,对于本身熟悉其他语言编程的朋友来说,肯定觉得很无聊。其实我是为了照顾本身对编程不是特别熟悉的朋友,上面的实验得出了一个结论,struct里面的变量定义,和一般的脚本语言没区别,作用域是优先当前结构本身,然后才是往上一级。然后如果要指定struct本身,可以使用this来指定。
然后关于public和private,也是和一般脚本区别不大,它可以通过一个public或者private标记一系列连着的变量和函数,

二、关于面向对象的思考

通过上面的例子,我们似乎看到了面向对象的一丝希望,对于复杂的逻辑,我们可以通过Struct结构定义类似于类(Class)的结构,然后把数据都封装在结构体的对象里面,然后定义方法,把处理的逻辑都写在结构体里面。最后,在外部调用时,只需要构建对象,并且传入数据,剩下的逻辑都在对象内部处理。
不过Struct不是Class,它的功能比较有限。比如如果按照严格的概念定义,面向对象应该包含封装、继承、多态。
从上面的例子看,Struct实现封装是没问题的,以为他有public和private的定义。
继承和多态,struct并没有直接现成的方法可以做到。如果非要说能实现继承,也可以通过定义一个方法,在创建子类的时候,把父类传进去,然后复制所有父类变量和方法的定义,最后在子类实现重写,覆盖父类的方法,也能勉强能实现。但我个人感觉,这样子做,变成了是为了实现面向对象而实现,好像有点跑偏了。
从我个人的理解,面向对象的目的是为了让代码变得条例清晰,便于管理。对象内部的问题对象自己解决,外部只负责调用和得到结果。基于这个理念,我觉得不一定非要实现继承和多态,只要在编写代码的时候能比较清晰的划分业务范围,就可以使用面向对象的方式去写maxscript的脚本了。

三、相对完整的应用例子

这里写了一个获取一个biped骨骼所有骨骼的信息的脚本,通过这个脚本,可以看看较为具体的写法。

1、完整代码:

(
	--function
	local CheckOneObj
	local PrintBoneInfo
	local OnPickFun
	local AddBoneInfoToDict
	local GetBoneInfoByName
	--var
	local TestPickUI
	local boneNameList;
	local boneDict
	struct TransformInfo
	(
		pos,
		rotation,
		scale,
		fn SetData obj =
		(
			this.pos = obj.transform.pos
			this.rotation = obj.transform.rotation
			this.scale = obj.transform.scale
		),		
		fn GetPrintString = 
		(
			local content = ""
			content += "pos:"+(this.pos as string)+"\n"
			content += "rotation:"+(this.rotation as string+"\n")
			content +="scale:"+(this.scale as string+"\n")
			return content
		)
	)
	

	
	struct BoneInfo
	(
		public
		name,
		transform,
		children,
		parent,
		fn SetData obj = 
		(
			this.name = obj.name
			this.transform = TransformInfo()
			this.transform.SetData obj
			this.SetParent obj
			this.SetChildren obj
			
		),
		fn GetInfoString = 
		(
			local content = this.GetNameString() + this.GetTransformString()+this.GetParentString()+this.GetChildrenString()
			return content
			
		),
		
		private 		
		fn SetParent obj = 
		(
			if obj.parent == undefined then
			(
				this.parent = undefined
			)
			else
			(
				this.parent = obj.parent.name
			)
		),
		fn SetChildren obj = 
		(
			local childrenList = obj.children
			if childrenList != undefined and childrenList.count >0 then
			(
				this.children = #()
				for i in 1 to childrenList.count do 
				(
					append this.children childrenList[i].name
				)
			)
			else
			(
				this.children = undefined
			)
		),		
		fn GetNameString = 
		(
			local content = "----------\n";
			if this.name == undefined then
			(
				content += "name:null\n"
			)
			else
			(
				content += "name:"+this.name+"\n";
			)
			return content
		),
		fn GetTransformString = 
		(
			local content = "";
			if this.transform != undefined then
			(
				content = "transform:\n";
				content += this.transform.GetPrintString()
			)
			else
			(
				content = "transform:null\n"
				
			)
			return content;
		),		
		
		fn GetParentString = 
		(
			local content = "";
			if this.parent == undefined then
			(
				content = "parent:null\n"
			)
			else
			(
				content = "parent:"+this.parent+"\n";
			)
			
		),
		
		
		fn GetChildrenString = 
		(
			local content = "";
			if this.children == undefined or this.children.count == 0 then
			(
				content = "children:null\n"
			)
			else
			(
				content = "children:"
				for i in 1 to this.children.count do
				(
					content += this.children[i]
					if i<this.children.count then
						content +=","
				)
				content +="\n"
				
				
			)
			return content
		)
		
	)
	
	fn AddBoneInfoToDict info = 
	(
		if boneNameList == undefined then
			boneNameList = #()
		if boneDict == undefined then
			boneDict = #()
		local index = findItem boneNameList info.name
		if index <=0 then
		(
			append boneNameList info.name
			append boneDict info
		)
		else
		(
			boneDict[index] = info
		)
	)
	
	fn GetBoneInfoByName val = 
	(
		if boneNameList == undefined or boneNameList.count == 0 then 
			return undefined
		
		local index = findItem boneNameList val
		if index <=0 then
		(
			return undefined
		)
		else
		(
			return boneDict[index]
		)
	)
	
	fn CheckOneObj obj = 
	(
		local info = BoneInfo()
		info.SetData obj
		AddBoneInfoToDict info
		local childrenList  = obj.children
		if childrenList != undefined and childrenList.count >0 then
		(
			for i in 1 to childrenList.count do
			(
				CheckOneObj childrenList[i];
			)
		)
	)
	
	fn PrintBoneInfo = 
	(
		if boneDict != undefined and boneDict.count >0 then
		(
			for i in 1 to boneDict.count do
			(
				print(boneDict[i].GetInfoString())
			)
		)
	)
	
	fn OnPickFun = 
	(
		if $ == undefined then
			return 0
		boneNameList = #()
		boneDict = #()
		CheckOneObj $
		PrintBoneInfo()
		
	)
	
	
	rollout TestPickUI "Untitled" width:199 height:177
	(
		button 'btn1' "pick" pos:[51,48] width:110 height:31 align:#left
		on btn1 pressed do
		(
			OnPickFun()
		)
	)
	createDialog TestPickUI
		
)

2、执行脚本的结果
运行脚本,会看到只有一个按钮:
在这里插入图片描述

创建一个biped骨骼
在这里插入图片描述

选择biped的根节点,然后点击pick按钮
在这里插入图片描述

会发现输出了很多打印。以横线分割,每一段是一根骨骼的信息。

3、代码说明:

1.struct的说明

这个脚本里面定义了2个结构体,分别是TransformInfo和BoneInfo。其中TransformInfo作为BoneInfo里面的一个变量,记录了骨骼的Transform信息。
BoneInfo除了Transform信息,还有名字、子节点、父节点的信息。
在使用方面,都是直接新建对应的对象,然后用SetData函数把物体对象传进去,然后在对象内部进行的数据分析和记录。
在最后,调用了BoneInfo的GetInfoString函数,获取物体的各种参数。而每一种属性的参数,都是有独立的方法去组建打印的字符串。如果想修改其中一种信息,可以只修改对应的方法。

2.数据存储

脚本里面有写函数,在这个例子里面是没有用到的,我是想顺便展示一下怎样去做这个事情。

fn AddBoneInfoToDict info = 
	(
		if boneNameList == undefined then
			boneNameList = #()
		if boneDict == undefined then
			boneDict = #()
		local index = findItem boneNameList info.name
		if index <=0 then
		(
			append boneNameList info.name
			append boneDict info
		)
		else
		(
			boneDict[index] = info
		)
	)
	
	fn GetBoneInfoByName val = 
	(
		if boneNameList == undefined or boneNameList.count == 0 then 
			return undefined
		
		local index = findItem boneNameList val
		if index <=0 then
		(
			return undefined
		)
		else
		(
			return boneDict[index]
		)
	)

本来事情很简单,如果有dictionary或者哈希表这类的数据类型,直接用key和value来存储是很简单的事情。但MaxScript并没有这样的类型,所以我就用其他方法实现了。
这里是建了了2个数组,一个是存储骨骼的名字boneNameList,一个是存储名字对应的对象boneDict,保证两个数组的下标是一样的,然后通过函数AddBoneInfoToDict添加数据,通过函数GetBoneInfoByName来获取数据,获取的时候,先通过名字判断是否在boneNameList数组里存在,如果存在,返回了下标,就通过下标去boneDict数组拿对象。

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

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

相关文章

3.5 方程组的状态与解的迭代改善

学习目标&#xff1a; 如果我要学习方程组的状态与解的迭代改善&#xff0c;我会采取以下步骤&#xff1a; 学习迭代方法的基本理论&#xff1a;首先&#xff0c;我会学习迭代方法的基本概念、原理和公式&#xff0c;包括雅可比迭代法、高斯-赛德尔迭代法和逐次超松弛迭代法等…

融合CDN行为分析动态加速解决方案

网络延迟对电商企业产生了巨大的负面影响&#xff0c;延迟是电子商务的杀手&#xff0c;网站访客等待的时间越长&#xff0c;最终实现转化的可能性就越小&#xff0c;同时他们对你的网站品牌的认可度也就越低&#xff0c;快速的网站内容交付是具有全球意识的电商企业不可或缺的…

Qt优秀开源项目之十八:QtService

QtService是一个用于实现Windows服务或unix守护进程的开源项目 github地址&#xff1a;https://github.com/qtproject/qt-solutions/tree/master/qtservice 源码可以编译成动态库&#xff0c;也可以直接在项目中引用源码 源码目录qtservice/examples中包含了三个例子&#xff0…

【Linux】system V 消息队列 | system V 信号量(简单赘述)

文章目录 1 . system V 消息队列(了解)接口查看消息队列 2.system V 信号量 (了解)1.进程互斥等概念的理解2.认识信号量3. 接口 这两部分主要是了解即可&#xff0c;为后面学习做铺垫 1 . system V 消息队列(了解) 为了让两个进程间通信 创建一个队列queue 进程A可以通过消息队…

Python——第2章 数据类型、运算符与内置函数

目录 1 赋值语句 2 数据类型 2.1 常用内置数据类型 2.1.1 整数、实数、复数 2.1.2 列表、元组、字典、集合 2.1.3 字符串 2.2 运算符与表达式 2.2.1 算术运算符 2.2.2 关系运算符 2.2.3 成员测试运算符 2.2.4 集合运算符 2.2.5 逻辑运算符 2.3 常用内置…

Kubernetes 笔记(15)— 应用保障、容器资源配额、容器状态探针概念及使用

作为 Kubernetes 里的核心概念和原子调度单位&#xff0c;Pod 的主要职责是管理容器&#xff0c;以逻辑主机、容器集合、进程组的形式来代表应用&#xff0c;它的重要性是不言而喻的。 在上层 API 对象的基础上&#xff0c;一起来看看在 Kubernetes 里配置 Pod 的两种方法&…

dell t630服务器风扇控制笔记记录(耗时一天)

1、打开虚拟控制台得用IE&#xff1b; 2、Dell PowerEdge T640 加装显卡之后风扇狂转问题解决 - 知乎 感谢知乎Billy&#xff0c; 操作步骤&#xff1a; 1、查看iDrac版本&#xff0c;必须在3.30.30.30及以下&#xff0c;之后的版本关闭了手动控制风扇转速的权限&#xff0…

从视图树到GPU:探索Android渲染机制

简介 在 Android 中&#xff0c;渲染技术可以分为 CPU 渲染和 GPU 渲染两种方式。CPU 渲染是直接使用 CPU 处理数据&#xff0c;并将其显示在屏幕上&#xff0c;而 GPU 渲染则是将数据传递给 GPU 进行处理和显示。 具体的渲染技术如下&#xff1a; Canvas绘图&#xff1a;An…

多层感知器介绍

一、概览 现实世界中很多真实的问题都不是线性可分的&#xff0c;即无法使用一条直线、平面或者超平面分割不同的类别&#xff0c;其中典型的例子是异或问题&#xff08;Exclusive OR&#xff0c;XOR&#xff09;&#xff0c;即假设输入为x1和x2&#xff0c;如果它们相同&…

Linux远程访问及控制SSH命令

目录 一. SSH服务1.1 SSH基础1.1.1什么是SSH服务器&#xff1f;1.1.2SSH优点1.1.3常见的ssh协议 二. 服务端配置文件常用选项2.1设置白名单2.2设置黑名单 三. SSH服务的两种验证方式3.1 公钥与私钥的关系 四. ssh客户端程序4.1ssh远程登录4.2 scp 远程复制4.3 sftp 安全的ftp 五…

Direct3D 12——计算着色器——计算着色器概念

计算着色器虽然是一种可编程的着色器&#xff0c;但Direct3D并没有将它直接归为渲染流水线中的一部分。虽然如此&#xff0c;但位于流水线之外的计算着色器却可以读写GPU资源。从本质上来说&#xff0c;计算着 色器能够使我们访问GPU来实现数据并行算法&#xff0c;而不必渲染出…

ESP32设备驱动-BH1745NUC 亮度和颜色传感器驱动

BH1745NUC 亮度和颜色传感器驱动 文章目录 BH1745NUC 亮度和颜色传感器驱动2、硬件准备3、软件准备4、驱动实现BH1745NUC 是具有 IC 总线接口的数字颜色传感器 IC。 该 IC 感应红光、绿光和蓝光 (RGB) 并将它们转换为数字值。 高灵敏度、宽动态范围和出色的 Ircut 特性使该 IC …

【CSS3】CSS3 伪元素字体图标 ( 生成 icommon 字体文件 | 字体图标基本使用 | 使用伪元素实现 icommon 字体图标显示 )

文章目录 一、icommon 字体图标基本使用1、生成 icommon 字体文件2、字体图标基本使用 二、使用伪元素实现 icommon 字体图标显示 一、icommon 字体图标基本使用 字体图标 指的是 将图标做成字体样式 , 在 放图标的地方 使用 文字 即可实现 图标显示 ; 1、生成 icommon 字体文件…

Vue2-黑马(十三)

目录&#xff1a; &#xff08;1&#xff09;实战-permissions.js-动态路由 &#xff08;2&#xff09;实战-第三方登录-流程分析 &#xff08;3&#xff09;实战-第三方登录-代码解读 &#xff08;1&#xff09;实战-permissions.js-动态路由 在做根据用户角色动态生成路由…

【Unity+MySQL】实现注册登录系统(升级版)

目录 1 UI界面重新设计1.1 注册界面1.2 登录界面1.3 交互实现 2 注册功能完善2.1 判断用户输入的用户名是否与数据库中的重复2.2 将当前时间更新至用户表的当前注册时间列2.3 将用户输入的注册密码使用哈希加密 3 登录功能完善 接着 上篇文章所谈到的系统缺陷&#xff0c;这篇…

==与equals()的理解

java中的数据类型分为基本数据类型、基本数据类型对应的包装类型&#xff08;引用类型&#xff09;&#xff0c;引用类型三种数据类型。 每一个基本类型java都提供了一个与之对应的包装类型&#xff0c;该包装类型是一个引用类型,并且在基本类型与包装类型之间提供了自动拆箱和…

AD21原理图----网络连线(网络线、网络标签、总线、差分对、信号线束)

目录 网络连线 网络线&#xff08;Wire&#xff09; 网络标签 总线 差分对 信号线束 网络连线 网络线&#xff08;Wire&#xff09; 网络标签 可以跨原理图 总线 用于放置同一类数据 使用步骤 第一步&#xff1a;先绘制网络线 第二步&#xff1a;利用网络标签进行连接&a…

虚拟机下Ubuntu系统的Docker部署

虚拟机下Ubuntu系统的微服务项目Docker部署 文章目录 虚拟机下Ubuntu系统的微服务项目Docker部署1、Ubuntu安装 Docker2、修改后端微服务的配置2.1 修改 MySQL 的配置2.2 修改 Redis 的配置2.3 修改 Nacos 的配置 3、生成微服务镜像4、拉取远程镜像5、生成前端镜像5.1 准备文件…

MacOS安装MongoDB与Redis

1.安装MongoDB: brew tap mongodb/brew brew install mongodb-community 后台服务方式运行mongodb: brew services restart mongodb/brew/mongodb-community 直接运行mongodb非后台服务 /usr/local/opt/mongodb-community/bin/mongod --config /usr/local/etc/mongod.con…

化工行业数字化“智能工厂”-解决方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 总体架构 设计理念—数据集成与流转 九大核心价值之一 九大核心价值之二 九大核心价值之三 九大核心价值之四 九大核心价值之五 九大核心价值之六 九大核心价值之七 九大核心…