Соответствующее владение часовней для полей - PullRequest
3 голосов
/ 08 марта 2019

Какое подходящее владение использовать для полей объекта, созданных в init?Я подумал, что лучше всего использовать «принадлежащий», но похоже, что он не сохраняет их после завершения инициализации.

Запуск этого кода ... ( Попробуйте онлайн! )

class Name {

    var text : string;

    //initializer
    proc init(name : string) {
        this.text = name;
    }

        proc writeThis(writer) {
        writer.writeln(this.text);
    }   
} //end of Name

class Monkey {

        var name : Name;
        var age : int;

        proc init(name : string, age : int) {
            this.name = new owned Name(name);
            this.age = age;
        }

    proc writeThis(writer) {
        writer.writeln("I'm a monkey named ", this.name, ", and I'm ", this.age, " years old.");
    }

} //end of class Monkey



var m = new owned Monkey("bananaface", 5);
writeln("m: ", m);

... заставляет его печатать только:

m: I'm a monkey named 

Попробуйте онлайн!

Что в инициате Обезьяны, чтобыло бы более подходящим владельцем, чем установка this.name = новое имя (...)?

1 Ответ

5 голосов
/ 09 марта 2019

Я попробовал вашу программу с предварительной версией 1.19 (которая скоро выйдет), и она распечатала

monkeys.chpl:20: In initializer:
monkeys.chpl:21: error: Field name would outlive the value it is set to

Теперь я объясню проблему:

class Name { ... }
class Monkey {
  var name : Name;
  proc init(name : string) {
    this.name = new owned Name(name);
  }
}

эквивалентно

class Name { ... }
class Monkey {
  var name : borrowed Name;
  proc init(name : string) {
    this.name = new owned Name(name);
  }
}

что совпадает с

class Name { ... }
class Monkey {
  var name : borrowed Name;
  proc init(name : string) {
    var tmp = new owned Name(name);
    this.name = tmp.borrow();
    // the instance in tmp is automatically deleted here
  }
}

И, возможно, вы можете более четко увидеть, что результат new owned уничтожается в конце инициализатора.

Исправление простое: объявите поле как var name: owned Name;:

class Name { ... }
class Monkey {
  var name : owned Name;
  proc init(name : string) {
    this.name = new owned Name(name);
  }
}
...