新特性:
一种新的 Mojo 原生字典类型,Dict用于存储键值对。Dict存储符合特征的值CollectionElement。键需要符合新的KeyElement特征,其他标准库类型尚未实现该特征。在短期内,您可以创建自己的包装类型来用作键。例如,以下示例定义一个StringKey类型并使用它创建一个将字符串映射到Int值的字典:
from collections.dict import Dict, KeyElement
@value
struct StringKey(KeyElement):
var s: String
fn __init__(inout self, owned s: String):
self.s = s ^
fn __init__(inout self, s: StringLiteral):
self.s = String(s)
fn __hash__(self) -> Int:
return hash(self.s)
fn __eq__(self, other: Self) -> Bool:
return self.s == other.s
fn main() raises:
var d = Dict[StringKey, Int]()
d["cats"] = 1
d["dogs"] = 2
print(len(d)) # prints 2
print(d["cats"]) # prints 1
print(d.pop("dogs")) # prints 2
print(len(d)) # prints 1
我们计划在后续版本中添加KeyElement对标准库类型的一致性。
-D MOJO_ENABLE_ASSERTIONS用户可以通过在调用编译源文件时指定来选择加入标准库代码中使用的断言mojo。在触发断言的情况下,断言消息将在程序退出之前与堆栈跟踪一起打印。默认情况下,出于性能原因,目前标准库中未启用断言。
Mojo 语言服务器现在实现了引用请求。IDE 使用它来提供对Go to References和Find All References的支持。当前的限制是不支持当前文档之外的引用,这将在将来解决。
该sys.info模块现在包括num_physical_cores()、num_logical_cores()、 和num_performance_cores()功能。
由仅内存类型组成的同质可变参数,例如String更强大且更易于使用。这些参数被投影到一个VariadicListMem.
(以前的版本使使用寄存器可传递类型的可变参数列表变得更容易,例如Int。)
现在,对 a 进行下标VariadicListMem会返回元素,而不是晦涩的内部类型。此外,我们现在支持inout可变owned参数:
fn make_worldly(inout *strs: String):
# This "just works" as you'd expect!
for i in range(len(strs)):
strs[i] += " world"
fn main():
var s1: String = "hello"
var s2: String = "konnichiwa"
var s3: String = "bonjour"
make_worldly(s1, s2, s3)
print(s1) # hello world
print(s2) # konnichiwa world
print(s3) # bonjour world
(以前的版本使使用可变参数列表变得更容易,但是下标VariadicListMem返回一个低级指针,这需要用户调用__get_address_as_lvalue()才能访问该元素。)
请注意,为可变参数列表添加下标可以像上面一样很好地工作,但是直接使用循环迭代可变参数列表for会产生 a Reference(如下所述)而不是所需的值,因此需要额外的下标;我们打算在未来解决这个问题。
fn make_worldly(inout *strs: String):
# Requires extra [] to dereference the reference for now.
for i in strs:
i[] += " world"
异构可变参数尚未转移到新模型,但会在未来的更新中转移。
请注意,对于可寄存器传递类型的可变参数(例如 ) ,可变参数列表包含值,而不是引用,因此不需要取消Int引用运算符 ( )。[]此代码继续像以前一样工作:
fn print_ints(*nums: Int):
for num in nums:
print(num)
print(len(nums))
Mojo 现在有一个安全Reference类型的原型版本。编译器的生命周期跟踪过程可以推断引用以安全地延长局部变量生命周期,并检查间接访问安全性。该Reference类型是全新的(并且当前没有语法糖),因此必须使用空下标显式取消引用它:ref[]提供对基础值的访问。
fn main():
var a : String = "hello"
var b : String = " references"
var aref = Reference(a)
aref[] += b
print(a) # prints "hello references"
aref[] += b
# ^last use of b, it is destroyed here.
print(aref[]) # prints "hello references references"
# ^last use of a, it is destroyed here.
虽然该Reference类型具有与 C 指针或 Mojo 类型相同的内存表示形式Pointer,但它还跟踪符号“生命周期”值,以便编译器可以推断出可能访问的值集。该生命周期是引用静态类型的一部分,因此它通过围绕它构建的通用算法和抽象进行传播。
该Reference类型可以形成对可变和不可变内存对象的引用,例如堆栈上的对象或借用/输入/拥有的函数参数。它是完全参数化的可变性,消除了由于可变性说明符而导致的代码重复问题,并为统一的用户级类型提供了基础。例如,它可用于实现处理可变和不可变数组切片的数组切片对象。
虽然这是 Mojo 生命周期系统向前迈出的重要一步,但它仍然处于早期阶段并且使用起来很困难。值得注意的是,没有使用引用的语法糖,例如自动取消引用。它的几个方面还需要进一步完善。它正在通过可变内存参数进行锻炼,这就是为什么它们现在开始表现得更好。
注意:安全Reference类型和不安全指针类型定义在同一个模块中,当前名为memory.unsafe. 我们希望在未来的版本中重组该模块。
Mojo 现在允许类型使用返回引用的计算访问器来实现refattr()和启用属性和下标语法。refitem()对于这些寻址内存中的值的常见情况,这为实现传统的获取/设置对提供了更方便且性能显着提高的替代方案。注意:将来当引用自动取消引用时,这可能会改变 - 那时我们可能会切换到仅返回来自 的引用getattr()。
已移除:
特殊takeinit的构造函数形式已从语言中删除。这种“非破坏性移动”操作之前已连接到x传输操作员中,但具有不一致的不可预测的行为。既然 Mojo 具有特征,最好将其建模为.take()类型上的显式操作,这将传输出类型的内容而不结束其生命周期。例如,对于保存指针的类型,take()可能会返回指向相同数据的新实例,并将其自己的内部指针清空。
此更改清楚地表明生命周期何时结束以及何时显式获取 LValue 的内容。
当前的自动调整实现已被弃用,因为 Mojo 的自动调整实现正在进行重新设计。围绕当前实现的教程也已被删除,因为它们正在被重写。
因此,autotune()、autotune_fork()和search()函数已从标准库中删除。
_OldDynamicVector仅适用于寄存器可传递元素类型的类型已被删除。请迁移到DynamicVector适用于寄存器传递和内存类型的用途。
in已被删除UnsafeFixedVector。utils.vector我们建议使用DynamicVector或InlinedFixedVector来代替。
装饰@adaptive器已从语言中删除。在非搜索上下文中装饰器的任何使用都可以替换为@parameter if. 例如:
@adaptive
fn foo[a: Bool]():
constrained[a]()
body1()
@adaptive
fn foo[a: Bool]():
constrained[not a]()
body2()
可以重写为:
fn foo[a: Bool]():
@parameter
if a:
body1()
else:
body2()
因此,特殊__adaptive_set属性也被删除。
结果参数已从 Mojo 中删除。函数参数列表中不再允许结果参数声明,也不再允许前向别名声明。这包括删除该param_return声明。
由于闭包模型的改进和改进,@noncapturing和装饰器已被删除。@closure请参阅下面的更多细节!
改变:
Mojo 闭合模型经过改进,更加简单和安全。Mojo 有两种闭包类型:参数闭包和运行时闭包。参数闭包可用于高阶函数,并且是vectorize和等函数的支柱parallelize。它们总是由 表示@parameter并具有类型fn() capturing -> T(其中T是返回类型)。
另一方面,运行时闭包始终是动态值,通过调用其复制构造函数来捕获值,并保留其捕获状态的所有权。您可以通过编写捕获值的嵌套函数来定义运行时闭包:
fn outer(b: Bool, x: String) -> fn() escaping -> None:
fn closure():
print(x) # 'x' is captured by calling String.__copyinit__
fn bare_function():
print("hello") # nothing is captured
if b:
# closure can be safely returned because it owns its state
return closure^
# function pointers can be converted to runtime closures
return bare_function
运行时闭包的类型采用以下形式fn() escaping -> T。您可以将等效的函数指针作为运行时闭包传递。
请继续关注移动捕获和引用捕获的捕获列表语法,以及更统一的闭包模型!
装饰@unroll(n)器现在可以采用展开因子的参数表达式,即 n可以是整数类型的参数表达式。
vectorize现在有一个重载size作为参数而不是参数传递。size这允许/的其余部分simd_width在单次迭代中运行。
cpython包中的模块已python移至内部模块,即_cpython.
AnyType并被Destructable统一为一个单一的特征,AnyType。每个标称类型(即所有结构)现在自动符合AnyType.
以前,该mojo package命令将输出一个 Mojo 包,其中包括部分编译的 Mojo 代码以及特定计算机体系结构(用于调用该命令的计算机体系结构)的完全编译的机器代码mojo package。
现在,mojo package仅包含部分编译的 Mojo 代码。它仅针对包首次import发布时所使用的特定计算机体系结构进行完全编译。因此,Mojo 包更小、更便携。
的simd_width和dtype参数polynomial_evaluate已切换。基于#1587中的请求,该polynomial_evaluate函数也被扩展,使得coefficients参数可以采用 a 或StaticTuplea VariadicList。
作为删除声明的一小步let,此版本删除了警告:'var' was never mutated, consider switching to a 'let'。