在 Pony 中,有很多地方可以省略语法或结构的基本元素,并期望用隐式默认值填充它们。您的问题的答案在这里关于隐式默认值的两个示例之间的区别Data1与Data2两个示例有关,这两个示例恰好不具有相同的功能。
该类Data2有一个构造函数 ,new create() => _x = 0它具有隐式默认接收器功能ref。也就是说,它隐式扩展为new ref create() => _x = 0。
该类Data1没有构造函数,因此 Pony 为您创建了一个隐式默认构造函数,即new iso create(). from 您的_x = 0字段声明也被隐式转移到构造函数的主体,但这有点超出了您的问题范围。
因此,在这种情况下,分配let d1: Data1 iso = Data1,因为创建的对象将是类型Data1 iso^,可以分配给Data1 iso。分配let d2: Data2 iso = Data2不起作用,因为创建的对象将是 type ,在不破坏隔离保证的情况下Data2 ref^不能分配给它。Data2 iso
Data2将构造函数更改为new iso create()是使示例代码工作的最佳解决方案。我们不将iso其用作构造函数的隐式默认功能,因为它会对构造函数的参数施加额外的约束(它们都必须是可发送的)。
为了完整起见,请注意在调用方还有另一种方法可以解决您的问题。如果将构造函数调用放在一个recover块中,则可以“提升”到具有更强保证的能力(例如 from refto iso)。这是有效的,因为该recover块对其中使用的对象引用实施了其他约束(例如,传递到恢复块的任何引用都必须是可发送的),这将维护您要提升的保证。这个任务看起来像:
let d2: Data2 iso = recover Data2 end