用actor替换class关键字会导致错误
这是我的密码:用actor替换class关键字会导致错误,class,actor,ponylang,Class,Actor,Ponylang,这是我的密码: class Eapproximator var step : F64 new create(step' :F64) => step = step' fun evaluate() :F64 => var total = F64(0) var value = F64(1) while total < 1 do total = total + step value = value + (value
class Eapproximator
var step : F64
new create(step' :F64) =>
step = step'
fun evaluate() :F64 =>
var total = F64(0)
var value = F64(1)
while total < 1 do
total = total + step
value = value + (value * step)
end
value
actor Main
new create(env: Env) =>
var e_approx = Eapproximator(0.00001)
var e_val = e_approx.evaluate()
env.out.print(e_val.string())
我能做些什么来解决这个问题?参与者是小马中的并发单元。这意味着同一程序中的许多不同参与者可以同时运行,包括
Main
和Eapproximator
参与者。现在,如果一个参与者的字段同时被多个参与者修改,会发生什么?由于并发程序在现代硬件上的工作方式,您最终很可能会得到一些垃圾值。这就是所谓的数据竞赛,它是并发编程中许多错误的根源。Pony的目标之一是在编译时检测数据竞争,而此错误消息是编译器告诉您您尝试执行的操作可能不安全
让我们浏览一下错误消息
接收器类型不是目标类型的子类型
接收器类型是被调用对象的类型,e_约
。目标类型是方法内部的this
类型,Eapproximator.evaluate
。子类型化意味着子类型的对象可以像父类型的对象一样使用。因此,该部分告诉您,由于类型不匹配,evaluate
无法在e_approx
上调用
接收器类型:Eapproximator标签
e_近似值
是一个Eapproximator标签
。标记
对象既不能读取也不能写入。我将在一分钟内详细说明为什么e_approx
是tag
目标类型:EAP Proximator box
此
内部的评估
是一个Eapproximator框
。框
对象可以读取,但不能写入这是框
,因为评估
被声明为fun evaluate
,这意味着fun box evaluate
(这意味着默认情况下,方法无法修改其接收者。)
Eapproximator标记不是Eapproxim的子类型
ator box:标记不是box的子映射
根据此错误消息,标记
对象不是框
对象的子类型,这意味着标记
不能像使用框一样使用。如果我们看一下标签
和框
允许什么,这是合乎逻辑的<代码>框
允许的内容多于标记
:它可以读取,而标记
不能读取。一个类型只能是另一个类型的子类型,如果它允许的内容少于(或等于)超类型
那么,为什么用actor
替换class
会使对象标记
?这与我前面提到的数据竞争问题有关。演员可以自由支配自己的领域。它可以读和写给他们。由于参与者可以并发运行,因此必须拒绝他们访问彼此的字段,以避免与字段所有者的数据竞争。而在类型系统中有一些东西正是这样做的:tag
。参与者只能将其他参与者视为标记
,因为读取或写入它们是不安全的。对于那些标记
引用,它可以做的主要有用的事情是发送异步消息(通过调用be
方法或行为),因为这既不是读也不是写
当然,由于您的程序中没有对Eapproximator
进行任何变异,因此您的特定病例是安全的。但是,试图禁止每一个不安全的程序要比试图允许除此之外的每一个安全程序容易得多
总而言之,除了将Eapproximator
作为一个类保留外,您的程序实际上没有任何修复方法。在小马节目中当演员不需要任何东西。参与者是并发性的单位,但这意味着它也是顺序性的单位。需要连续和同步的计算必须在单个参与者中进行。然后,您可以将这些计算分解为不同的类,以保持良好的代码卫生
Error:
/src/main/main.pony:18:34: receiver type is not a subtype of target type
var e_val = e_approx.evaluate()
^
Info:
/src/main/main.pony:18:17: receiver type: Eapproximator tag
var e_val = e_approx.evaluate()
^
/src/main/main.pony:6:3: target type: Eapproximator box
fun evaluate() :F64 =>
^
/src/main/main.pony:3:3: Eapproximator tag is not a subtype of Eapproxim
ator box: tag is not a subcap of box
new create(step' :F64) =>
^
Error:
/src/main/main.pony:19:19: cannot infer type of e_val
env.out.print(e_val.string())