1

Data1 和 Data2 的实例具有不同功能的解释是什么?

实例化 Data1 类的对象的行编译没有问题,但是 Data2 get 的行是错误说"right side must be a subtype of left side"

class Data1 
  let _x: U8 = 0

class Data2
  let _x: U8
  new create() => _x = 0

actor Main
  new create(env: Env) =>
    let d1: Data1 iso = Data1
    let d2: Data2 iso = Data2
4

1 回答 1

4

在 Pony 中,有很多地方可以省略语法或结构的基本元素,并期望用隐式默认值填充它们。您的问题的答案在这里关于隐式默认值的两个示例之间的区别Data1Data2两个示例有关,这两个示例恰好不具有相同的功能。

该类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
于 2017-02-01T20:13:23.630 回答