我很难将元素添加到保留通用值集合的对象中。我尝试了一个最小的工作示例,该示例会导致错误:
class OneElementQueue {
type eltType;
var elements : [0..0] eltType;
//initializer
proc init(type eltType) {
this.eltType = eltType;
}
proc add(element : eltType) {
this.elements[0] = element;
}
proc remove() : eltType {
return this.elements[0];
}
} //end of OneElementQueue
class Monkey {
var name: string;
var age: int;
proc init(name : string, age : int) {
this.name = name;
this.age = age;
}
} //end of class Monkey
var q = new owned OneElementQueue(Monkey);
var m = new owned Monkey("Kyle", 6);
q.add(m);
当我尝试编译所有这些时,我会收到一个错误:
$ chpl BadQueue.chpl
BadQueue.chpl:12: In function 'add':
BadQueue.chpl:13: error: Scoped variable would outlive the value it is set to
BadQueue.chpl:12: note: consider scope of element
$
在这样的通用数据结构中添加一些东西的正确方法是什么?我怎么以错误的方式?
您可以在这里采用两种可能的方法,具体取决于您想要的行为:
"我想让我的收藏品拥有对猴子对象的所有权"
在这种情况下,您需要实例化OneElementQueue
集合以存储owned Monkey
对象,而不是简单的[borrowed] Monkey
对象,这是类类型的默认值。您可以使用一行更改来执行此操作(在线尝试):
var q = new owned OneElementQueue(owned Monkey);
在这种方法中,将owned Monkey
传递给您的add()
方法将将所有权传递给参数,并最终转移到集合,从而使原始对象参考无效(nil
)。
"我想让我的收藏借入现有的猴子对象而无需拥有它们的所有权"
在这种情况下,您需要告诉add()
方法,参数传递给了参数本身将超过参数本身(然后确保不要对此撒谎)。在Chapel版本1.19中,可以通过终生注释完成:
proc add(element : eltType) lifetime element > this {
注释lifetime element > this
断言,通过element
传递的实际参数将超过this
收集本身,因此编译器不应担心一旦正式论证具有一旦借贷就会停止。
Chapel 1.18中没有寿命注释,因此,如果您使用该版本,则需要使用稍大的锤子并将pragma "unsafe"
应用于该方法。请注意,布拉格马斯不是官方支持的功能,并且可能会在将来发生变化,因此,在这种情况下,在实施了生命周期注释之前,它一直是秒盖的(在线尝试):
pragma "unsafe"
proc add(element : eltType) {