由于范围原因,不允许向 class 中的通用集合添加值
Adding value to generic collection in class not allowed because of scope
我在向保存通用类型值集合的对象中添加元素时遇到问题。我尝试了一个导致错误的最小工作示例:
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
$
向这样的通用数据结构添加内容的正确方法是什么?我怎么弄错了?
这里有两种可能的方法,具体取决于您想要的行为:
"I want to have my collection take ownership of the Monkey objects"
在这种情况下,您需要实例化 OneElementQueue
集合来存储 owned Monkey
个对象,而不是简单地 [borrowed] Monkey
个对象,后者是 class 的默认设置类型。您可以通过一行更改 (Try it Online):
来做到这一点
var q = new owned OneElementQueue(owned Monkey);
在这种方法中,将 owned Monkey
传递给您的 add()
方法会将所有权传递给参数并最终传递给集合,从而使原始对象引用无效 (nil
) .
"I want to have my collection borrow the existing Monkey objects without taking ownership of them"
在这种情况下,您需要告诉 add()
方法传递给它的参数将比参数本身更有效(然后确保不要撒谎)。在 Chapel 1.19 版本中,这可以通过生命周期注解来完成:
proc add(element : eltType) lifetime element > this {
其中注释lifetime element > this
断言通过element
传递的实际参数将比this
集合本身存在,所以编译器不应该担心借用一次就会不复存在正式论证有。
Chapel 1.18 中不提供生命周期注解,因此如果您使用的是该版本,则需要使用稍大的锤子并将 pragma "unsafe"
应用于该方法。请注意,pragma 不是官方支持的功能,将来可能会更改,因此对于这种情况,在实现生命周期注释之前用作权宜之计 (Try it Online):
pragma "unsafe"
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
$
向这样的通用数据结构添加内容的正确方法是什么?我怎么弄错了?
这里有两种可能的方法,具体取决于您想要的行为:
"I want to have my collection take ownership of the Monkey objects"
在这种情况下,您需要实例化 OneElementQueue
集合来存储 owned Monkey
个对象,而不是简单地 [borrowed] Monkey
个对象,后者是 class 的默认设置类型。您可以通过一行更改 (Try it Online):
var q = new owned OneElementQueue(owned Monkey);
在这种方法中,将 owned Monkey
传递给您的 add()
方法会将所有权传递给参数并最终传递给集合,从而使原始对象引用无效 (nil
) .
"I want to have my collection borrow the existing Monkey objects without taking ownership of them"
在这种情况下,您需要告诉 add()
方法传递给它的参数将比参数本身更有效(然后确保不要撒谎)。在 Chapel 1.19 版本中,这可以通过生命周期注解来完成:
proc add(element : eltType) lifetime element > this {
其中注释lifetime element > this
断言通过element
传递的实际参数将比this
集合本身存在,所以编译器不应该担心借用一次就会不复存在正式论证有。
Chapel 1.18 中不提供生命周期注解,因此如果您使用的是该版本,则需要使用稍大的锤子并将 pragma "unsafe"
应用于该方法。请注意,pragma 不是官方支持的功能,将来可能会更改,因此对于这种情况,在实现生命周期注释之前用作权宜之计 (Try it Online):
pragma "unsafe"
proc add(element : eltType) {