Добавление значения в общую коллекцию в классе не разрешено из-за области действия - PullRequest
0 голосов
/ 01 марта 2019

У меня проблемы с добавлением элементов в объект, который хранит коллекцию значений общего типа.Я попытался минимальный рабочий пример, который вызывает ошибку:

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
$

Как правильно поступитьо добавлении чего-то в общую структуру данных, как это?Как я поступаю неправильно?

1 Ответ

0 голосов
/ 01 марта 2019

Здесь есть два возможных подхода, в зависимости от того, какое поведение вы хотите:

«Я хочу, чтобы моя коллекция стала владельцем объектов Monkey»

В этом случае вы захотите создать экземпляр вашей коллекции OneElementQueue для хранения owned Monkey объектов, а не просто [borrowed] Monkey объектов, что по умолчанию для типов классов.Вы можете сделать это с изменением в одну строку (попробуйте онлайн) :

var q = new owned OneElementQueue(owned Monkey);

При таком подходе передача owned Monkey в ваш метод add() передаст владениеаргумент и, в конечном итоге, на коллекцию, что делает исходную ссылку на объект недействительной (nil).

«Я хочу, чтобы моя коллекция заимствовала существующие объекты Monkey, не вступая во владение ими» *

В этом случае вам нужно сообщить методу add(), что переданный в него аргумент переживет сам аргумент (и затем убедитесь, что он не лжет).В версии 1.19 Chapel это можно сделать с помощью аннотаций времени жизни:

proc add(element : eltType) lifetime element > this {

, где аннотация lifetime element > this утверждает, что фактический аргумент, переданный через element, переживет саму коллекцию this, поэтому компиляторне следует опасаться, что заем прекратит свое существование после формального аргумента.

Пожизненные аннотации не были доступны в часовне 1.18, поэтому, если вы используете эту версию, вам нужно использовать чуть больший молоток и применить pragma "unsafe" к методу.Обратите внимание, что прагмы не являются официально поддерживаемой функцией и могут измениться в будущем, поэтому в этом случае она служила временным ограничением до тех пор, пока не были реализованы аннотации времени жизни (Попробуйте онлайн) :

pragma "unsafe"
proc add(element : eltType) {
...