Mojo 现在支持 ` comptime@` 关键字作为 `@` 的同义词alias。` comptime@` 关键字可以与 `@` 互换使用,alias用于编译时声明。这两个关键字都完全受支持,并且行为完全相同。例如:
comptime x = 5 # New preferred syntaxalias y = 10 # Still fully supportedcomptime MyType[T: AnyType] = T # Works with parametric declarations
注意:未来的更新会将错误信息和内部术语迁移到“comptime”关键字。alias目前仍将保留该关键字以保持向后兼容性。
Mojo 现在支持使用单个语句解包不在结构体或 trait 中的别名/计算时间元组。例如:
comptime i, f = (1, 3.0)comptime q, v = divmod(4, 5)
问题 #3925:Mojo 现在允许基于“拥有”或“按引用”参数约定重载方法,当给定一个“拥有”值时选择“拥有”重载,否则选择“按引用”版本。这使得算法效率更高,例如使用迭代器而不是借用迭代器:
struct MyCollection: fn __iter__(var self) -> Self.ConsumingIterator: ... fn __iter__(self) -> Self.BorrowingIterator: ...
集合字面量现在有了默认类型。例如,现在你可以将集合字面量绑定 [1,2,3]到T函数中, fn zip[T: Iterable](impl:T)因为该函数定义的类型将默认为标准库的List类型。
Mojo 现在有一个__functions_in_module()实验性的内部函数,允许对调用它的模块中声明的函数进行反射。例如:
fn foo(): passdef bar(x: Int): passdef main(): alias funcs = __functions_in_module() # equivalent to: alias same_funcs = Tuple(foo, bar)
该内部函数目前仅限于在函数内部使用。有关在测试套件中 main()使用示例,请参阅“使用 TestSuite 运行测试”。__functions_in_module()
装饰@implicit器现在接受一个可选的deprecated关键字参数。这可以用来逐步淘汰隐式转换,而不是仅仅移除装饰器(移除装饰器可能会导致另一个意想不到的隐式转换路径)。例如,编译器现在会针对以下情况发出警告:
struct MyStuff: @implicit(deprecated=True) fn __init__(out self, value: Int): passfn deprecated_implicit_conversion(): # warning: deprecated implicit conversion from 'IntLiteral[1]' to 'MyStuff' _: MyStuff = 1 _ = MyStuff(1) # this is okay, because the conversion is already explicit.
装饰@deprecated器现在可以接受一个带有use关键字参数的目标符号。这与现有的位置字符串参数互斥。系统将自动生成弃用警告。
@deprecated(use=new)fn old(): passfn new(): passfn main(): old() # 'old' is deprecated, use 'new' instead
在声明了参数化__call__()方法但未声明下标方法(__getitem__()、、__setitem__()或 __getattr__())的 struct 实例中,__call__()现在可以使用参数调用该方法:
struct Callable: fn __init__(out self): pass fn __call__[x: Int](self, y: Int) -> Int: return x + y fn main(): var c = Callable() print(c[1](2)) # 3
以前你需要明确地查找__call__():
print(c.__call__[1](2))
新增了DType.float4_e2m1fn4 位浮点e2m1格式。该 类型由开放计算 MX 规范Float4_e2m1定义 。
deinit现在,方法可以将所有内容转移self到另一种deinit方法。
Mojo 现在在用它构建的程序中使用系统分配器 mojo build --sanitize address。这意味着 ASan 可以看到 Mojo 的堆分配情况,并且现在应该能够检测到更多的堆内存错误。
UnsafePointer已更名为, 并由LegacyUnsafePointer 一个新的 UnsafePointer替代 。同样,也已更名为 ,并由一个新的 替代。主要区别在于参数的顺序,现在如下所示:OpaquePointerLegacyOpaquePointerOpaquePointer
struct UnsafePointer[ mut: Bool, //, # Inferred mutability type: AnyType, origin: Origin[mut], # Non-defaulted origin *, address_space: AddressSpace = AddressSpace.GENERIC,]alias OpaquePointer[ mut: Bool, //, # Inferred mutability origin: Origin[mut], # Non-defaulted origin *, address_space: AddressSpace = AddressSpace.GENERIC,] = UnsafePointer[NoneType, origin, address_space=address_space]
其隐式构造函数现在不再允许在具有不同可变性和原始值的指针之间进行不安全类型转换。代码需要更新到新的类型UnsafePointer,但在此期间,用户可以查找并替换当前对旧指针类型的使用,UnsafePointer并将其重命名为新类型 LegacyUnsafePointer。另一种方法是,用户可以在任何依赖旧指针类型的文件的开头添加以下导入语句:
from memory import LegacyUnsafePointer as UnsafePointer# and/or if you use OpaquePointerfrom memory import LegacyOpaquePointer as OpaquePointer
在此迁移期间,用户还可以使用as_legacy_pointer()转换as_unsafe_pointer() 方法在两种指针类型之间进行转换。
注意:LegacyUnsafePointer此功能LegacyOpaquePointer最终将在 Mojo 的未来版本中弃用并移除。
有一些新的实用类型别名UnsafePointer:
MutUnsafePointer
ImmutUnsafePointer
MutOpaquePointer
ImmutOpaquePointer
最后,alloc()它已从静态方法移至UnsafePointer独立alloc()函数。因此,之前编写的代码如下:
var ptr = UnsafePointer[Int].alloc(3)
必须改为:
var ptr = alloc[Int](3)
有关迁移到新版本的更多详细信息,请参阅UnsafePointer v2 提案UnsafePointer中提供的迁移指南 。
添加了一个swap_pointees()函数,作为指针可能相互别名时UnsafePointer的替代方案 。swap()
origin_cast()`for` LayoutTensor和 NDBuffer`and`UnsafePointer已被弃用并移除。LayoutTensor现在NDBuffer支持更安全的 as_any_origin()源类型转换方法。`and`UnsafePointer具有相同的安全替代方案,此外,它还具有安全as_immutable() 类型转换函数以及显式不安全unsafe_mut_cast()类型 unsafe_origin_cast()转换方法。
源empty已重命名为external。此源表示 Mojo 生命周期检查器未跟踪的值。从 处新分配的内存alloc()将随源一起返回MutOrigin.external。
更名MutableOrigin为MutOrigin和。ImmutableOriginImmutOrigin
更名MutableAnyOrigin为MutAnyOrigin和。ImmutableAnyOrigin ImmutAnyOrigin
memcpy()不 parallel_memcpy()带关键字参数的写法已被弃用。
SpanStringSlice 现在构造函数接受长度 Int参数而不是默认值UInt。这一变化使得这些类型在使用整数字面量和其他 Int基于整数的 API 时更加方便。
新增了Span.binary_search_by()使用自定义比较器函数进行二分查找的功能。
unsafe_get()已添加unsafe_swap_elements()到unsafe_subspan()结构Span体中。
Optional现在符合 Iterable并Iterator作为大小为 1 或 0 的集合。
模块中添加了新的ContiguousSlice 类型 ,以支持无步长切片的特殊化。StridedSlicebuiltin_slice
List现在,不使用步长进行切片会返回一个值Span,而不是一个值List,并且不再分配内存。
为了提高人体工程学效率,多个标准库 API 已更新为使用 `int`Int而不是 `int` UInt ,从而无需在使用 Int值时进行显式类型转换(整数字面量和循环索引的默认类型):
BitSet[size: Int]- 将参数从更改UInt为Int
BitSet.set(idx: Int),,,BitSet.clear(idx: Int)-从BitSet.toggle(idx: Int)更改 为BitSet.test(idx: Int)``UInt``Int
String(unsafe_uninit_length: Int)- 从UInt到Int
String.capacity() -> Int- 将返回类型从更改UInt为Int
String.reserve(new_capacity: Int)- 从UInt到Int
List(length: Int, fill: T)- 从UInt到Int
Codepoint.unsafe_write_utf8() -> Int- 将返回类型从更改UInt为 Int
Codepoint.utf8_byte_length() -> Int- 将返回类型从更改UInt为 Int
模块新增了repeat()一个函数 itertools,用于创建一个迭代器,该迭代器会将元素重复指定次数。与 Python 的迭代器不同itertools.repeat(),目前不支持无限迭代——times必须指定迭代次数参数。用法示例:
from itertools import repeatfor val in repeat(42, times=3): print(val) # Prints: 42, 42, 42
如果元组元素的类型也可比较,则现在支持比较操作。例如,现在可以(1, "a") == (1, "a")这样 写:`Tuple( ...1( ( ( ( ) 元素的类型可比较) 类型可比较) 元素类型可比较(1, "a") < (1, "b"))元素类型可比较` 元组(Tuple(Tuple(Tuple(Tuple(T
现在,错误和警告信息comptime在许多情况下会保留别名,以防止复杂类型的类型名称过长。编译器会在必要时根据简单的启发式方法展开这些别名,以便理解类型,例如:
struct Dep[T: AnyType, v: T]: passalias MyDep[T: AnyType, v: T] = Dep[T, v]alias MyDepGetAlias0 = MyDep.hello
产生:
$ mojo t.mojot.mojo:10:29: error: 'MyDep' needs more parameters bound before accessing attributesalias MyDepGetAlias0 = MyDep.hello ^t.mojo:10:29: note: 'MyDep' is aka 'alias[T: AnyType, v: T] Dep[T, v]'
如果需要公开更多信息,请提交问题报告。
现在,错误消息会保留对always_inline("builtin") 函数的符号调用,而不是将其内联到错误消息中。
此版本包含多项针对函数展开错误的改进。函数展开器是编译器的一个阶段,在此阶段确定最终参数值并将参数化代码转换为具体代码。函数展开过程中常见的错误包括“函数实例化失败”和“调用展开失败”消息,这些错误是由于确定实际参数值与任何可行的函数重载都不匹配而导致的。
生成器还会检查约束(使用该 constrained()函数定义),因此在此过程中会生成约束失败。
现在,详细报错会报告完整的调用实例化失败路径。对于此 Mojo 文件:
fn fn1[T: ImplicitlyCopyable, //] (a: T): constrained[False]()fn fn2[T: ImplicitlyCopyable, //] (a: T): return fn1(a)fn main(): fn2(1)
现在错误信息会打印路径,main -> fn2 -> fn1 -> constrained[False] 而不是仅仅打印路径constrained[False]。
现在,程序展开错误会打印出一些无关紧要的参数值,即使调用展开失败也会如此。例如,对于这个简单的 Mojo 程序:
fn fn1[a: Int, b: Int](): constrained[a < b]()fn fn2[a: Int, b: Int](): fn1[a, b]()fn main(): fn2[4, 2]()
现在错误信息显示parameter value(s): ("a": 4, "b": 2):
test.mojo:6:14: note: call expansion failed with parameter value(s): ("a": 4, "b": 2) fn1[a, b]()
默认情况下,现在只输出字符串和数值,其他值将显示为.... 使用--elaboration-error-verbose可以显示所有参数值。
默认情况下,与前奏相关的展开错误信息会被省略。前奏是指从 `<module>` 导出的一组 API stdlib/builtin/_startup.mojo。这些 API 存在于所有调用展开路径中,但很少是报告错误的根源。为了简化展开错误信息,现在默认情况下会省略这些 API。
用于--elaboration-error-include-prelude包含前奏。
默认情况下(不含前奏):
test.mojo:43:4: error: function instantiation failed fn main(): ^test.mojo:45:12: note: call expansion failed my_func()...
前奏:
open-source/max/mojo/stdlib/stdlib/builtin/_startup.mojo:119:4: error: function instantiation failedfn __mojo_main_prototype( ^open-source/max/mojo/stdlib/stdlib/builtin/_startup.mojo:119:4: note: call expansion failed with parameter value(s): (...)open-source/max/mojo/stdlib/stdlib/builtin/_startup.mojo:42:4: note: function instantiation failedfn __wrap_and_execute_main[ ^open-source/max/mojo/stdlib/stdlib/builtin/_startup.mojo:68:14: note: call expansion failed main_func() ^test.mojo:43:4: note: function instantiation failedfn main(): ^test:45:12: note: call expansion failed my_func()...
`and` 命令--elaboration-error-limit新增了一个选项。此选项用于限制打印的分析错误数量。默认值为 20。要更改此限制,请使用 ` limit` 参数,其中 ` limit`为 20 表示无限制。mojo run``mojo build``--elaboration-error-limit=``0
--help-hidden所有 Mojo CLI 命令都已添加显示隐藏选项的选项。
mojo debug现在拒绝debug目标和未知选项。
Mojo 语言服务器现在将报告更连贯的代码操作。
CLImojo现在新增了一个--experimental-fixit标志,可以自动应用解析器发出的 FixIt 提示。此功能尚处于高度实验阶段,用户在使用前应确保备份文件(或将其提交到源代码控制系统中)。
问题 #5111: 现在可以在编译时对math.cos()and函数进行求值。math.sin()
修复了IntTuple.value(i)当元素以嵌套的单元素元组形式存储时,该方法返回错误值的问题。此前,调用 该方法Layout.row_major(M, N).stride.value(i)会返回负偏移值(例如 -65536、-65537),而不是实际的步长值。这会影响任何使用该value()方法访问布局步长或形状值的代码。
修复了LayoutTensor.shape[idx]()嵌套布局下方法返回错误值的问题。该错误发生在访问具有嵌套布局的张量的形状维度时,例如((32, 2), (32, 4)),该方法会返回错误值而不是正确的乘积(例如,64)。
修复了不同内存布局张量之间的 LayoutTensor逐元素算术运算(例如,,,,+)的问题。此前,当操作数的内存布局不同时,类似这样的运算会产生错误的结果,因为两个操作数错误地使用了相同的布局索引。现在,它会根据每个张量的内存布局正确地计算出不同的索引。-``*``/``a.transpose() - b
修复了LayoutTensor.shape[idx]()嵌套布局下方法返回错误值的问题。该错误发生在访问具有嵌套布局的张量的形状维度时,例如((32, 2), (32, 4)),该方法会返回错误值而不是正确的乘积(例如,64)。
修复了处理嵌套布局结构的 arange()函数。此前,该函数在填充包含嵌套布局的张量时会失败,因为它试图从嵌套元组中提取形状值的方式不正确。layout._fillers``Layout(IntTuple(IntTuple(16, 8), IntTuple(32, 2)), ...)
问题 #5479__del__ :编译没有结构体上下文的独立函数时,Mojo 崩溃。
第 5500 号问题:新增了关于 GPU 目标配置和 LLVM 数据布局字符串的详细文档gpu/host/info.mojo。该文档现在包含所有 MLIR 目标组件的详细说明、NVIDIA/AMD/Apple GPU 的厂商特定模式、添加新 GPU 架构的分步指南以及获取数据布局字符串的实用方法。
问题 #5492:修复了 FileHandle“rw”模式意外截断文件内容的问题。现在,使用“rw”模式打开文件时,open(path, "rw")能够正确保留现有文件内容,并允许读写操作,类似于 Python 的“r+”模式。此前,“rw”模式会立即截断文件,导致无法读取现有内容,并可能造成数据丢失。
问题 #3849:新增了对文件打开时追加模式(“a”)的支持。该open()函数现在接受“a”作为有效模式,即以追加模式打开文件。以追加模式打开的文件,写入的内容将添加到文件末尾,而不会截断现有内容。如果文件不存在,则会创建该文件。
问题 #3208:修复了 FileHandle在写入模式下打开 FIFO(命名管道)时出现“无法删除现有文件”错误的问题。open(path, "w")现在可以正常打开 FIFO、设备和套接字等特殊文件。此前,写入模式会在打开文件之前尝试删除现有文件,但对于不应删除的特殊文件,此操作会失败。
问题 #5142:该 sys.intrinsics.compressed_store函数现在包含一个debug_assert用于捕获空指针使用情况的函数,提供清晰的错误消息,而不是因段错误而崩溃。
现在sys.intrinsics.strided_load(),` __init__` sys.intrinsics.strided_store()、` sys.intrinsics.masked_load()__init__`、`__init__` 和 `__init__`函数都包含一个用于捕获空指针使用情况的函数,从而提供清晰的错误消息,而不是因段错误而崩溃。sys.intrinsics.masked_store()``debug_assert()
现在该logger软件包会以彩色打印液位信息。
deinit现在抛出异常的方法能够理解self错误路径中已取消初始化,从而避免对隐式析构函数进行冗余调用,并改进线性类型支持。