Parallel processing 由于作用域的原因,不允许向类中的泛型集合添加值

Parallel processing 由于作用域的原因,不允许向类中的泛型集合添加值,parallel-processing,hpc,chapel,Parallel Processing,Hpc,Chapel,我在向保存泛型类型值集合的对象添加元素时遇到问题。我尝试了一个导致错误的最小工作示例: class OneElementQueue { type eltType; var elements : [0..0] eltType; //initializer proc init(type eltType) { this.eltType = eltType; } proc add(element : eltType) {

我在向保存泛型类型值集合的对象添加元素时遇到问题。我尝试了一个导致错误的最小工作示例:

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
集合来存储
拥有的Monkey
对象,而不是简单地存储
[借用的]Monkey
对象,这是类类型的默认值。您可以通过一行更改来完成此操作:

在这种方法中,将
owned Monkey
传递给
add()
方法将所有权传递给参数,并最终传递给集合,从而使原始对象引用无效(
nil

“我想让我的收藏借用现有的Monkey对象,而不占用它们的所有权”

在这种情况下,您需要告诉
add()
方法,传入它的参数将比参数本身更有效(然后确保不要撒谎)。在Chapel版本1.19中,这可以通过终生注释完成:

proc add(element : eltType) lifetime element > this {
其中注释
lifeive element>this
断言通过
element
传递的实际参数将超过
this
集合本身的寿命,因此编译器不应担心一旦形式参数被删除,借用将不再存在

Chapel 1.18中没有生命周期注释,因此如果使用该版本,则需要使用稍大的锤子,并将
pragma“unsafe”
应用于该方法。请注意,pragmas不是官方支持的功能,将来可能会发生变化,因此在这种情况下,在实现生命周期注释之前,pragmas只是权宜之计:


后续:如果我想在一个地方创建代码中的对象,然后将它们放入数据结构,然后将它们带到其他地方,我需要将它们作为“非托管”启动,并确保在另一端使用它们后删除它们。是这样吗?(在这种情况下,在第19版之前我必须使用不安全的pragma。)如果“取出”的意思是“永久”,那么不,您仍然可以使用
owned
。这样一个对象最初由程序中的变量
m
拥有,然后所有权转移到数据结构,然后当对象被移除时,所有权将转移到另一侧捕获对象的变量。然后,当保存该对象的最后一个变量超出范围时,该对象将被删除。您也可以采用您描述的方法,使用
unmanaged
,并注意自己删除该变量。但在本例中,编译器不会尝试对变量的生存期进行任何推理,因此不需要使用pragma<代码>非托管是告诉编译器“你不必担心这个,我会的。”而
拥有的
会导致编译器内的生存期检查,而
共享的
会导致执行时间引用计数。
proc add(element : eltType) lifetime element > this {
pragma "unsafe"
proc add(element : eltType) {