ExplicitlyCopyable
表示只能通过显式调用方法才能复制的类型.copy()
。
绝大多数类型默认实现Copyable
(因此是隐式可复制的),并且ExplicitlyCopyable
已部分分阶段实施,但在使用上存在很大的限制。
现在,新的Copyable
trait 表示一种可以 显式复制的类型(使用.copy()
),并且ImplicitlyCopyable
可以使用新的“标记”trait 来选择使类型也隐式可复制。这将默认行为从隐式可复制切换为仅显式可复制。
新的ImplicitlyCopyable
特征继承自Copyable
,并且不需要额外的方法。ImplicitlyCopyable
编译器特意知道。(ImplicitlyCopyable
也可以使用明确复制类型 .copy()
。)
这使得非隐式可复制类型能够与所有标准库功能一起使用,解决了 Mojo 长期以来强制所有类型隐式可复制的问题。这将使 Mojo 程序更加高效、可读性更强,并减少意外隐式复制导致的性能和正确性问题。
通过此更改,符合以下条件的类型Copyable
不再可隐式复制:
@fieldwise_initstruct Person(Copyable): var name: Stringfn main(): var p = Person("Connor") var p2 = p # ERROR: not implicitly copyable var p3 = p.copy() # OK: may be copied explicitly
为了使类型能够隐式复制,请声明符合 ImplicitlyCopyable
标记特征:
@fieldwise_initstruct Point(ImplicitlyCopyable): var x: Float32 var y: Float32fn main(): var p = Point(5, 10) var p2 = p # OK: may be implicitly copied var p3 = p.copy() # OK: may be explicitly copied
另一个细微差别是,ImplicitlyCopyable
只能对字段全部为自身ImplicitlyCopyable
(而不仅仅是 Copyable
)的类型进行合成。如果需要使任何非 字段的类型ImplicitlyCopyable
支持隐式复制,则可以声明符合 ImplicitlyCopyable
,但__copyinit__()
手动编写定义:
struct Container(ImplicitlyCopyable): var x: SomeCopyableType var y: SomeImplicitlyCopyableType fn __copyinit__(out self, existing: Self): self.x = existing.x.copy() # Copy field explicitly self.y = existing.y
有关可复制性的更多信息,请参阅Mojo 手册中有关复制构造函数的部分 。