class 与构造函数的不同能力
different capability for class with constructor
Data1和Data2的实例具有不同的能力是什么解释?
实例化 Data1 class 的对象的行编译没有问题,但带有 Data2 的行得到的错误是 "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
在 Pony 中,有很多地方可以省略语法或结构的基本元素,并期望它们用隐式默认值填充。关于 Data1
和 Data2
之间区别的问题的答案与隐式默认值的两个示例有关,它们恰好不具有相同的功能。
Data2
class 有一个构造函数,new create() => _x = 0
,它有一个隐含的默认接收器能力 ref
。也就是说,它隐式扩展为 new ref create() => _x = 0
.
Data1
class没有构造函数,所以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
块中,则可以 "lift" 到具有更强保证的功能(例如,从 ref
到 iso
)。这是有效的,因为 recover
块对其中使用的对象引用强制执行其他约束(例如,传递到恢复块的任何引用必须是可发送的),这将支持您提升到的保证。这个作业看起来像:
let d2: Data2 iso = recover Data2 end
Data1和Data2的实例具有不同的能力是什么解释?
实例化 Data1 class 的对象的行编译没有问题,但带有 Data2 的行得到的错误是 "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
在 Pony 中,有很多地方可以省略语法或结构的基本元素,并期望它们用隐式默认值填充。关于 Data1
和 Data2
之间区别的问题的答案与隐式默认值的两个示例有关,它们恰好不具有相同的功能。
Data2
class 有一个构造函数,new create() => _x = 0
,它有一个隐含的默认接收器能力 ref
。也就是说,它隐式扩展为 new ref create() => _x = 0
.
Data1
class没有构造函数,所以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
块中,则可以 "lift" 到具有更强保证的功能(例如,从 ref
到 iso
)。这是有效的,因为 recover
块对其中使用的对象引用强制执行其他约束(例如,传递到恢复块的任何引用必须是可发送的),这将支持您提升到的保证。这个作业看起来像:
let d2: Data2 iso = recover Data2 end