朱莉娅中是否存在某种空IOStream?

时间:2019-04-30 15:59:59

标签: julia

在我正在研究的Julia模块中,我需要能够存储多个文件,这些文件可以在代码的不同部分动态写入。 因此,我创建了一个看起来像这样的可变结构。

mutable struct foo
    file_1::IOStream
    file_2::IOStream
    file_3::IOStream
end

在生成IOStream之前,我将如何初始化这样的内容,我尝试了以下方法,但是它们似乎不起作用。

foobar = foo(undef,undef,undef)

foobar = foo(nothing, nothing, nothing)

foobar = foo(0,0,0)

但是它们似乎都不起作用。

2 个答案:

答案 0 :(得分:2)

如果要允许创建未初始化的mutable struct,则可以为这样的示例定义内部构造函数:

mutable struct foo
    file_1::IOStream
    file_2::IOStream
    file_3::IOStream

    foo() = new()
end

现在,当您拥有:

julia> foobar = foo()
foo(#undef, #undef, #undef)

当然,在访问foobar的字段之前,您必须为其分配一些值。

您可以检查是否使用foobar分配了isdefined的字段,例如isdefined(foobar, :field_1)。唯一的不便之处在于,如果您编写类似isdefined并返回isdefined(foobar, :field_100)的情况,false也将起作用(因此,必须确保您正在检查现有字段,例如使用fieldnames函数或hasfield函数;后者仅在Julia 1.2中可用)

另一种方法是通过以下方式定义foo

mutable struct foo
    file_1::Union{IOStream, Nothing}
    file_2::Union{IOStream, Nothing}
    file_3::Union{IOStream, Nothing}

    foo(file_1=nothing, file_2=nothing, file_3=nothing) =
        new(file_1, file_2, file_3)
end

(在这种情况下,您可以忽略定义内部构造函数)

现在您可以写:

julia> foobar = foo()
foo(nothing, nothing, nothing)

此方法的好处是您可以安全地访问foobar的字段并测试其值,例如:

julia> foobar.file_1 === nothing
true

编辑

从另一个角度回到原始问题,有一个devnull变量,该变量丢弃所有写入其中的数据。但是,其类型为Base.DevNull,它是IO的子类型。因此,您还可以编写:

mutable struct foo
    file_1::Union{IOStream, Base.DevNull}
    file_2::Union{IOStream, Base.DevNull}
    file_3::Union{IOStream, Base.DevNull}

    foo() = new(devnull, devnull, devnull)
end

通过这种方式,您可以一直写入file_1file_2file_3,并且默认情况下,您写入的内容将被丢弃。

答案 1 :(得分:0)

我发现我可以制作一个空的IOStream并在以后对其进行编辑,以使它看起来像这样:

foobar = foo(IOStream(string()),IOStream(string()),IOStream(string()))