具有构造函数的类的不同功能

时间:2017-02-01 19:46:11

标签: ponylang

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

实例化Data1类对象的行编译没有问题,但是Data2的行得到的错误是"右侧必须是左侧的子类型&#34 ;

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

1 个答案:

答案 0 :(得分:4)

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

Data2类有一个构造函数new create() => _x = 0,其隐式默认接收器功能为ref。也就是说,它隐式扩展为new ref create() => _x = 0

Data1类没有构造函数,因此Pony为您创建了一个隐式默认构造函数,即new iso create()。您的字段声明中的_x = 0也会隐式转移到构造函数的主体,但这有点超出了您的问题的范围。

因此,在这种情况下,分配let d1: Data1 iso = Data1,因为创建的对象将是Data1 iso^类型,可以分配给Data1 iso。分配let d2: Data2 iso = Data2不起作用,因为创建的对象将是Data2 ref^类型,在不破坏隔离保证的情况下无法分配给Data2 iso

Data2构造函数更改为new iso create()是使示例代码正常工作的最佳解决方案。我们不使用iso作为构造函数的隐式默认功能,因为它会对构造函数的参数设置额外的约束(它们都必须是可发送的)。

为了完整起见,请注意您的问题还有其他方法,在来电方面。如果您将构造函数调用放在recover块中,则可以“提升”到具有更强保证的功能(例如,从refiso)。这是有效的,因为recover块对其中使用的对象引用强制执行其他约束(例如,任何传入recover块的引用必须是可发送的),这将保留您要解除的保证。这个任务看起来像:

    let d2: Data2 iso = recover Data2 end