Mojo数据类型详解

Mojo 中的所有值都分配有相对应的数据类型,大多数类型都是由结构体定义的标称的类型。这些类型是标称的(或“命名的”),因为类型相等性是由类型的名称而不是其结构决定的。

有一些类型未定义为结构,例如下面的两种情况:

  • 函数是根据其签名进行输入的。
  • NoneType是一种具有一个实例(即None对象)的类型,用于表示“无值”。

Mojo附带了一个标准库,提供了许多有用的类型和实用函数。这些标准类型不是特权类型。每个标准库类型的定义都与用户定义类型一样,甚至包括 Int和 等基本类型String。但这些标准库类型是在大多数 Mojo 程序中使用的构建块。

最常见的类型是内置类型,它们始终可用且无需导入。这些类型包括数值(numeric)、字符串(strings)、布尔值(boolean)等类型。

标准库还包含许多可根据需要导入的类型,包括集合(collection)类型、用于与文件系统交互和获取系统信息的实用程序等。

Numeric types


它表示系统支持的最大尺寸的有符号整数——通常为 64 位或 32 位。

Mojo 还具有各种精度的整数和浮点值的内置类型:

Type nameDescription
Int88-bit signed integer
UInt88-bit unsigned integer
Int1616-bit signed integer
UInt1616-bit unsigned integer
Int3232-bit signed integer
UInt3232-bit unsigned integer
Int6464-bit signed integer
UInt6464-bit unsigned integer
Float1616-bit floating point number (IEEE 754-2008 binary16)
Float3232-bit floating point number (IEEE 754-2008 binary32)
Float6464-bit floating point number (IEEE 754-2008 binary64)

表 1.具有特定精度的数字类型

表 1 中的类型实际上都是单一类型的别名, SIMD稍后将讨论。

所有数字类型都支持常见的数字和位运算符。math模块提供了许多附加数学函数。

您可能想知道何时使用Int以及何时使用其他整数类型。通常,Int当您需要整数类型并且不需要特定位宽时,这是一个不错的安全默认设置。将其用作IntAPI 的默认整数类型可使 API 更加一致和可预测。

Floating-point numbers


浮点类型表示实数。由于并非所有实数都能用有限位数表示,因此浮点数无法准确表示每个值。表 1 中列出的浮点类型Float64— 、Float32和 Float16— 遵循 IEEE 754-2008 标准来表示浮点值。每种类型都包含一个符号位、一组表示指数的位和另一组表示分数或尾数的位。表 2 显示了每种类型在内存中的表示方式。

Type nameSign(符号)Exponent(指数)Mantissa(尾数)
Float641 bit11 bits52 bits
Float321 bit8 bits23 bits
Float161 bit5 bits10 bits

表 2.浮点类型的详细信息

指数值为全 1 或全 0 的数字表示特殊值,允许浮点数表示无穷大、负无穷大、有符号零和非数字 (NaN)。有关如何表示数字的更多详细信息,请参阅Wikipedia 上的IEEE 754。

对于浮点值,有几点需要注意:

  • 四舍五入误差,四舍五入可能会产生意外结果。例如,1/3 无法在这些浮点格式中准确表示。对浮点数执行的运算越多,四舍五入误差就越大。
  • 连续数字之间的间距。连续数字之间的间距在浮点数格式的范围内是可变的。对于接近零的数字,连续数字之间的距离非常小。对于较大的正数和负数,连续数字之间的间距大于 1,因此可能无法表示连续的整数。

由于这些值是近似值,因此用相等运算符 ( ==) 进行比较很少有用。请注意以下示例:

var big_num = 1.0e16
var bigger_num = big_num+1.0
print(big_num == bigger_num)

在这里插入图片描述
运行结果为:True
较运算符(< >=等等)适用于浮点数。您还可以使用该math.isclose()函数比较两个浮点数在指定的公差范围内是否相等。

Numeric literals


除了这些数字类型之外,标准库还提供整数和浮点文字类型, IntLiteral以及 FloatLiteral。

这些文字类型在编译时用于表示代码中出现的文字数字。一般来说,您永远不应该自己实例化这些类型。

表 3 总结了可以用来表示数字的文字格式。

FormatExamples(例子)Notes(注释)
Integer literal1760Integer literal, in decimal format.(整数文字,十进制格式。)
Hexadecimal literal0xaa, 0xFFInteger literal, in hexadecimal format.Hex digits are case-insensitive.(整数文字,采用十六进制格式。十六进制数字不区分大小写。)
Octal literal0o77Integer literal, in octal format.(整数文字,八进制格式。)
Binary literal0b0111Integer literal, in binary format.(整数文字,二进制格式。)
Floating-point literal3.14, 1.2e9Floating-point literal.Must include the decimal point to be interpreted as floating-point.(浮点文字。必须包含小数点才能解释为浮点。)

表 3.数字文字格式

在编译时,文字类型是任意精度(也称为无限精度)值,因此编译器可以执行编译时计算而不会出现溢出或舍入错误。

在运行时,这些值将转换为有限精度类型——Int对于整数值,Float64对于浮点值。(将只能在编译时存在的值转换为运行时值的过程称为具体化。)

以下代码示例显示了任意精度计算与运行时使用值进行的相同计算之间的差异Float64,后者存在舍入误差。

var arbitrary_precision = 3.0 * (4.0 / 3.0 - 1.0)
# use a variable to force the following calculation to occur at runtime
var three = 3.0
var finite_precision = three * (4.0 / three - 1.0)
print(arbitrary_precision, finite_precision)

运行结果如下图:
在这里插入图片描述

SIMD and DType


为了支持高性能数字处理,Mojo 使用类型 SIMD作为其数字类型的基础。SIMD(单指令、多数据)是一种处理器技术,允许您一次对整个操作数集执行操作。Mojo 的 SIMD类型抽象了 SIMD 操作。一个SIMD值表示一个 SIMD 向量— 即一个固定大小的值数组,可以放入处理器的寄存器中。SIMD 向量由两个参数定义 :

  • 一个DType值,定义向量中的数据类型(例如,32 位浮点数)。
  • 向量中元素的数量,必须是 2 的幂。
var vecr = SIMD[DType.float32, 4](3.0, 2.0, 2.0, 1.0)

对 SIMD 值的数学运算以元素为单位应用于向量中的每个单独元素。例如:

var vec1 = SIMD[DType.int8, 4](2, 3, 5, 7)
var vec2 = SIMD[DType.int8, 4](1, 2, 3, 4)
var product = vec1 * vec2
print(product)

执行结果如下图:
在这里插入图片描述

Scalar values


该SIMD模块定义了几种类型别名,它们是不同类型SIMD向量的简写。具体来说,Scalar类型只是一个 具有单个元素的向量。表 1SIMD中列出的数字类型 ,如和,实际上是不同类型标量值的类型别名:Int8Float32

alias Scalar = SIMD[size=1]
alias Int8 = Scalar[DType.int8]
alias Float32 = Scalar[DType.float32]

这乍一看可能有点令人困惑,但这意味着无论您处理的是单个Float32值还是 float32 值的向量,数学运算都会经过完全相同的代码路径。

The DType type


该DType结构描述了向量可以容纳的不同数据类型SIMD,并定义了许多用于操作这些数据类型的实用函数。该DType结构定义了一组别名,用作不同数据类型的标识符,例如DType.int8和DType.float32。声明向量时可以使用这些别名SIMD:

var v: SIMD[DType.float64, 16]

请注意,DType.float64不是类型,而是描述数据类型的值。您不能创建类型 的变量DType.float64。您可以创建类型SIMD[DType.float64, 1](或 Float64,它们是同一件事)的变量。

from utils.numerics import max_finite, min_finitedef describeDType[dtype: DType]():print(dtype, "is floating point:", dtype.is_floating_point())print(dtype, "is integral:", dtype.is_integral())print("Min/max finite values for", dtype)print(min_finite[dtype](), max_finite[dtype]())
describeDType[DType.float32]()

执行结果如下:
在这里插入图片描述
float32 是浮点数:True float32 是积分:False float32 的最小/最大有限值 -3.4028234663852886e+38 3.4028234663852886e+38

标准库中还有其他几种数据类型也使用DType抽象。

Strings


Mojo 的String类型表示可变字符串。(对于 Python 程序员,请注意,这与 Python 的标准字符串不同,后者是不可变的。)字符串支持多种运算符和常用方法。

var s: String = "Testing"
s += " Mojo strings"
print(s)

执行结果如下图:
在这里插入图片描述
大多数标准库类型都符合该 Stringable特征,该特征表示可以转换为字符串的类型。用于str(value)显式将值转换为字符串:

var s = str("Items in list: ") + str(5)
print(s)

执行结果如下图:
在这里插入图片描述

String literals


与数字类型一样,标准库包含一个字符串文字类型,用于表示程序源中的文字字符串。字符串文字用单引号或双引号括起来。

相邻的文字连接在一起,因此您可以使用分成多行的一系列文字来定义一个长字符串:

var s = "A very long string which is ""broken into two literals for legibility."

要定义多行字符串,请将文字括在三个单引号或双引号中:

var s = """
Multi-line string literals let you 
enter long blocks of text, including 
newlines."""

请注意,三重双引号形式也用于 API 文档字符串。

IntLiteral与和不同FloatLiteral,StringLiteral不会自动实现为运行时类型。在某些情况下,您可能需要 使用内置 方法手动将StringLiteral值转换为。Stringstr()

例如,如果要将字符串文字连接到其他类型,则需要先转换StringLiteral为String值。这是因为许多类型可以隐式转换为String,但不能转换为StringLiteral。

# print("Strings play nicely with others: " + True)
# Error: ... right hand side cannot be converted from Bool to StringLiteral
print(str("Strings play nicely with others: ") + str(True))

运行结果是:

Strings play nicely with others: True

Booleans


Mojo 的Bool类型表示布尔值。它可以采用两个值之一, True或False。您可以使用运算符对布尔值取反not。

var conditionA = False
var conditionB: Bool
conditionB = not conditionA
print(conditionA, conditionB)

输出结果:

False True

许多类型都有布尔表示。任何实现该 Boolable特征的类型都有布尔表示。作为一般原则,如果集合包含任何元素,则计算结果为 True,如果集合为空,则计算结果为 False;如果字符串的长度不为零,则计算结果为 True。

Collection types


Mojo 标准库还包含一组基本集合类型,可用于构建更复杂的数据结构:

  • List,一个动态大小的项目数组。
  • Dict,一个键值对的关联数组。
  • Set,无序的唯一项目集合。
  • Optional 表示可能存在或不存在的值。

集合类型是泛型类型:虽然给定的集合只能保存特定类型的值(例如Int或),但你可以在编译时使用参数Float64指定类型。例如,你可以像这样创建一个值:ListInt

var l = List[Int](1, 2, 3, 4)
# l.append(3.14) # error: FloatLiteral cannot be converted to Int

您并不总是需要明确指定类型。如果 Mojo 可以推断类型,则可以省略它。例如,当您从一组整数文字构造列表时,Mojo 会创建一个List[Int]。

# Inferred type == Int
var l1 = List(1, 2, 3, 4)

如果您需要更灵活的集合,则该 Variant类型可以保存不同类型的值。例如,a可以在任何给定时间Variant[Int32, Float64]保存Int32 或值。(本节不介绍如何使用,有关更多信息,请参阅API 文档。)Float64Variant

以下部分对主要的收集类型进行简单介绍。

List


List是一个动态大小的元素数组。列表元素需要符合特征 CollectionElement,这意味着项目必须是可复制和可移动的。大多数常见的标准库原语,如Int、String和SIMD都符合此特征。您可以List通过将元素类型作为参数传递来创建一个,如下所示:

var l = List[String]()

该List类型支持 Python listAPI 的子集,包括附加到列表、从列表中弹出项目以及使用下标符号访问列表项的功能。

from collections import Listvar list = List(2, 3, 5)
list.append(7)
list.append(11)
print("Popping last item from list: ", list.pop())
for idx in range(len(list)):print(list[idx], end=", ")

输出结果:

Popping last item from list:  11
2, 3, 5, 7,

请注意,上面的代码示例在创建列表时省略了类型参数。由于列表是使用一组Int值创建的,因此 Mojo 可以 根据参数推断出类型。

使用时存在一些明显的限制List:

  • 您当前无法从列表文字初始化列表,如下所示:
# Doesn't work!
var list: List[Int] = [2, 3, 5]

但您可以使用可变参数来实现同样的效果:

var list = List(2, 3, 5)

您不能print()列出列表,或将其直接转换为字符串。

# Does not work
print(list)

如上所示,只要它们属于同一Stringable类型,您就可以打印列表中的各个元素。

  • 迭代 aList当前会返回 Reference每个项目的 a,而不是项目本身。您可以使用取消引用运算符访问该项目[]:
#: from collections import List
var list = List(2, 3, 4)
for item in list:print(item[], end=", ")

执行结果:

2, 3, 4,

但是,列表中的下标会直接返回该项目 - 无需取消引用:

#: from collections import List
#: var list = List[Int](2, 3, 4)
for i in range(len(list)):print(list[i], end=", ")

输出为:

2, 3, 4,

Dict


该Dict类型是一个保存键值对的关联数组。您可以Dict通过指定键类型和值类型作为参数来创建,如下所示:

var values = Dict[String, Float64]()

字典的键类型必须符合 KeyElement特征,值元素也必须符合 CollectionElement特征。

您可以插入和删除键值对、更新分配给键的值以及遍历字典中的键、值或项目。

迭代Dict器都产生引用,因此需要使用取消引用运算符,[]如下例所示:

from collections import Dictvar d = Dict[String, Float64]()
d["plasticity"] = 3.1
d["elasticity"] = 1.3
d["electricity"] = 9.7
for item in d.items():print(item[].key, item[].value)

输出:

plasticity 3.1000000000000001
elasticity 1.3
electricity 9.6999999999999993

Set


该Set类型表示一组唯一值。您可以在集合中添加和删除元素、测试集合中是否存在某个值,以及执行集合代数运算,例如两个集合之间的并集和交集。

集合是通用的,并且元素类型必须符合 KeyElement特征。

from collections import Seti_like = Set("sushi", "ice cream", "tacos", "pho")
you_like = Set("burgers", "tacos", "salad", "ice cream")
we_like = i_like.intersection(you_like)print("We both like:")
for item in we_like:print("-", item[])

输出:

We both like:
- ice cream
- tacos

Optional


表示Optional 可能存在也可能不存在的值。与其他集合类型一样,它是通用的,可以保存符合该 CollectionElement特征的任何类型。


# Two ways to initialize an Optional with a value
var opt1 = Optional(5)
var opt2: Optional[Int] = 5
# Two ways to initalize an Optional with no value
var opt3 = Optional[Int]()
var opt4: Optional[Int] = None

当 包含值时,Optional其计算结果为,否则为 。如果包含值,则可以使用 方法来检索对该值的引用。但是,在没有值的情况下调用会导致未定义的行为,因此您应该始终 在检查值是否存在的条件中保护对 的调用。TrueFalseOptionalvalue()value()Optionalvalue()

var opt: Optional[String] = str("Testing")
if opt:var value_ref = opt.value()print(value_ref)

输出:

Testing

或者,您可以使用该or_else()方法,如果存在则返回存储的值,否则返回用户指定的默认值:

var custom_greeting: Optional[String] = None
print(custom_greeting.or_else("Hello"))custom_greeting = str("Hi")
print(custom_greeting.or_else("Hello"))

输出:

Hello
Hi

Register-passable, memory-only, and trivial types


在文档的多个地方,您会看到对可传递寄存器类型、仅传递内存类型和简单类型的引用。可传递寄存器类型和仅传递内存类型根据其保存数据的方式进行区分:

寄存器可传递类型完全由固定大小的数据类型组成,这些数据类型(理论上)可以存储在机器寄存器中。寄存器可传递类型可以包含其他类型,只要它们也是寄存器可传递的。 例如Int,、Bool和SIMD都是寄存器可传递类型。因此,寄存器可传递类型struct可以包含Int和Bool字段,但不能包含 String字段。寄存器可传递类型用 @register_passable装饰器声明。

寄存器可传递类型总是按值传递(即,复制值)。

仅内存类型由任何不符合寄存器可传递类型描述的类型组成。具体来说,这些类型通常具有指向动态分配内存的指针或引用。String、List和Dict都是仅内存类型的示例。

我们的长期目标是让用户清楚地了解这一区别,并确保所有 API 都适用于可传递寄存器类型和仅内存类型。但现在您会看到一些标准库类型仅适用于可传递寄存器类型或仅适用于仅内存类型。

除了这两个类别之外,Mojo 还有“简单”类型。从概念上讲,简单类型只是一种在其生命周期方法中不需要任何自定义逻辑的类型。组成简单类型实例的位可以被复制或移动,而无需知道它们的作用。目前,简单类型是使用装饰器声明的 @register_passable(trivial) 。简单类型不应仅限于寄存器可传递类型,因此未来我们打算将简单类型与装饰 器分开@register_passable。

AnyType and AnyTrivialRegType


在 Mojo API 中您会看到的另外两个东西是对AnyType和 的 引用AnyTrivialRegType。它们实际上是元类型,即类型的类型。

AnyType代表任意 Mojo 类型。Mojo 被视为AnyType一种特殊特质,您可以在 特质页面找到更多相关讨论。
AnyTrivialRegType是一个元类型,代表任何标记为寄存器可通过的 Mojo 类型。
您会在这样的签名中看到它们:

fn any_type_function[ValueType: AnyTrivialRegType](value: ValueType):...

您可以将其理解为具有一个类型为的 any_type_function参数,其中是可通过寄存器传递的类型,该类型在编译时确定。valueValueTypeValueType

标准库中仍然有一些类似的代码,但它正在逐渐迁移到更通用的代码,这些代码不区分可寄存器传递类型和仅内存类型。

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

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

相关文章

百款精选的HTML5小游戏源码,你可以下载并直接运行在你的小程序或者自己的网站上

今天我带来了一份特别的礼物——百款精选的HTML5小游戏源码&#xff0c;你可以下载并直接运行在你的小程序或者自己的网站上&#xff0c;只需双击index.html即可开始。无论你是在寻找创意引流&#xff0c;还是想为你的网站增添互动性&#xff0c;这些小游戏都能帮你实现&#x…

办公必备!一键把PDF转换为PPT文件,只需这3款神器!

在当今数字化办公环境中&#xff0c;文件格式的转换已成为提高工作效率的关键因素之一。其中&#xff0c;PDF(便携式文档格式)和PPT(PowerPoint演示文稿)是两种广泛使用的文件格式。然而&#xff0c;有时我们需要将PDF文件转换为PPT格式&#xff0c;以便进行编辑或演示。 为方…

数据结构的基本概念与算法

数据结构的基本概念与算法 什么是数据&#xff1f; 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合&#xff1b;总结来说 -> 数据就是计算机程序加工的原料&#xff1b; 数据元素、数据项&#xf…

<数据集>棉花识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;13765张 标注数量(xml文件个数)&#xff1a;13765 标注数量(txt文件个数)&#xff1a;13765 标注类别数&#xff1a;4 标注类别名称&#xff1a;[Partially opened, Fully opened boll, Defected boll, Flower] 序…

Java面试——Tomcat

优质博文&#xff1a;IT_BLOG_CN 一、Tomcat 顶层架构 Tomcat中最顶层的容器是Server&#xff0c;代表着整个服务器&#xff0c;从上图中可以看出&#xff0c;一个Server可以包含至少一个Service&#xff0c;用于具体提供服务。Service主要包含两个部分&#xff1a;Connector和…

SQL labs-SQL注入(七,sqlmap对于post传参方式的注入,2)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。参考&#xff1a;SQL注入之Header注入_sqlmap header注入-CSDN博客 序言&#xff1a; 本文主要讲解基于SQL labs靶场&#xff0c;sqlmap工具进行的post传参方式的SQL注入&#xff0c…

【Java版数据结构】初识泛型

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;Java版数据结构 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…

【全国大学生电子设计竞赛】2024年E题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

快速查找WGS1984 坐标地理坐标系转UTM投影坐标的多种方法

在arcgis中如果是要计算长度或面积&#xff0c;则需要将矢量图层地理坐标系转为投影坐标系&#xff0c;下面总结了几种快速找到“WGS 1984”&#xff08;UTM ZONE&#xff09;投影带号的方法。 一、准备工作 软件&#xff1a;arcmap 示例数据&#xff1a;安微省shp矢量图 二…

删除链表的倒数第N个结点(LeetCode)

题目 给你一个链表&#xff0c;删除链表的倒数第个结点&#xff0c;并且返回链表的头结点。 示例1&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例2&#xff1a; 输入&#xff1a;&#xff0c; 输出&#xff1a; 示例3&#xff1a; 输入&#xff1a;&#x…

申瓯通信设备有限公司在线录音管理系统(复现过程)

漏洞简介 申瓯通信设备有限公司在线录音管理系统 index.php接口处存在任意文件读取漏洞&#xff0c;恶意攻击者可能利用该漏洞读取服务器上的敏感文件&#xff0c;例如客户记录、财务数据或源代码&#xff0c;导致数据泄露 一.复现过程 fofa搜索语句:title"在线录音管…

【Vue3】标签的 ref 属性

【Vue3】标签的 ref 属性 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。…

Ubuntu22.04手动安装fabric release-2.5版本

这个过程稍微有点复杂&#xff0c;但完整操作完成以后会对Fabric网络有更加深入的理解&#xff0c;方便后续自己手动搭建Fabric网络。这个过程需要手动逐个下载Fabric源代码、使用命令下载Fabric镜像和用Git下载例子程序。 Fabric源代码主要用途是用来编译cryptogen、configtx…

二叉搜索树(图解)

文章目录 二叉搜索树的概念插入查找二叉搜索树的删除操作删除单孩子和叶子节点。del节点有两个孩子用左子树的最大节点替代用右子树的最小节点替代 弊端 二叉搜索树的概念 对于每颗子树&#xff0c;左子树 < 根&#xff0c;右子树 > 根。 二叉搜索树有以下操作&#xff1…

代码随想录二刷(哈希表)

代码随想录二刷(哈希表) 三数之和思路反正对于我来说是真的难想出来。 若这道题还是采用哈希表的思路去做&#xff0c;非常麻烦&#xff0c;并且还要考虑去重的操作。所以这道题其实用双指针&#xff0c;是更方便的。 具体程序如下&#xff1a; class Solution:def threeSu…

Docker简介和Docker常见命令

目录 1. Docker 简介 1.1 Docker 的核心概念 1.2 Docker 的优势 1.3 Docker 工作流程 2. 常见命令 2.1 基本命令 2.2 镜像操作 2.3 容器操作 2.4 网络操作 2.5 卷操作 2.6 日志和监控 2.7 清理命令 3. 注意事项和最佳实践 3.1 镜像操作 3.2 容器操作 3.3 网络操…

2.1、matlab绘图汇总(图例、标题、坐标轴、线条格式、颜色和散点格式设置)

1、前言 在 MATLAB 中进行绘图是一种非常常见且实用的操作,可以用来可视化数据、结果展示、分析趋势等。通过 MATLAB 的绘图功能,用户可以创建各种类型的图形,包括线图、散点图、柱状图、曲线图等,以及三维图形、动画等复杂的可视化效果。 在绘图之前,通常需要先准备好要…

docker部署容器端口占用问题

docker部署容器端口占用问题 当我在使用 Windows 下使用 Docker Desktop 部署docker容器时经常性发生容器启动失败的提示&#xff0c;并且有的时候重启电脑后就能成功启动容器&#xff0c;这是因为 Hyper-V 引起的 保留端口&#xff0c;这部分端口将会被系统保留&#xff0c;无…

基于SpringBoot+Vue的企业客户信息反馈平台(带1w+文档)

基于SpringBootVue的企业客户信息反馈平台(带1w文档) 基于SpringBootVue的企业客户信息反馈平台(带1w文档) 企业客户信息反馈平台的开发运用java技术&#xff0c;MIS的总体思想&#xff0c;以及MYSQL等技术的支持下共同完成了该平台的开发&#xff0c;实现了企业客户信息反馈管…

【C++】哈希容器

unordered系列关联式容器 在之前的博文中介绍过关联式容器中的map与set&#xff0c;同map与set一样&#xff0c;unordered_set与unordered_set也是关联式容器。 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;查询效率可以达到logN&#xff1b;在…