以下代码是另一个使用通道创建类的尝试。在这里,我直接从调用方传递一个通道,而不是在类中打开它。虽然代码给出了预期的结果,但我想知道做这样的事情是否合法,特别是通过在openwriter()
语句中直接调用new
(如baa
的情况)。换句话说,只要存在引用底层文件的变量(这里是output
中的Myclass
),即使实际的通道变量是临时的,也可以假设文件保持打开状态?
class Myclass
{
var output: channel;
proc init( output = stdout )
{
this.output = output;
}
}
proc main()
{
var foo = new owned Myclass();
foo.output.writeln( 10 ); // written to stdout
var baa = new owned Myclass( openwriter("test.out") );
baa.output.writeln( 20 ); // written to file
baa.output.writeln( 30 );
}
是的,这应该继续有效,因为文件和渠道都是参考计数。
另见https://chapel-lang.org/docs/modules/standard/IO.html#functions-for-closing-channels
另请注意,在当前时间,Chapel中的临时变量在封闭块的末尾被销毁(而不是在语句的末尾,这是C ++的作用)。在这种情况下无关紧要,因为在语句var baa = ...
完成之前,通道的引用计数将在MyClass初始化程序中增加。这有时会令人惊讶(参见https://github.com/chapel-lang/chapel/issues/11492),因此我们正在考虑调整(参见https://github.com/chapel-lang/chapel/issues/11534)。
我相信你的代码应该是正常的。文件和通道的文档表明它们是引用计数的,因此只要某个变量引用它们,它们就应该保持活跃状态。以下引用来自Functions for Closing Channels上的1.19版文档:
文件和频道是参考计数。当没有引用它时,每个文件和通道都会自动关闭。例如,如果局部变量是对通道的唯一引用,则当该变量超出范围时,将关闭该通道。程序还可以显式关闭文件或通道。