Reputation: 452
In the Julia module I'm working on, I need to be able to store multiple files that I can write to dynamically at different parts in the code. So I've created a mutable struct that looks something like this.
mutable struct foo
file_1::IOStream
file_2::IOStream
file_3::IOStream
end
how would I go about initialising something like this before I generate the IOStream, I've tried the following, but they don't seem to work.
foobar = foo(undef,undef,undef)
foobar = foo(nothing, nothing, nothing)
foobar = foo(0,0,0)
But none of them seem to work.
Upvotes: 1
Views: 252
Reputation: 69949
If you want to allow for creation of an uninitialized mutable struct
you can define an inner constructor fro example like this:
mutable struct foo
file_1::IOStream
file_2::IOStream
file_3::IOStream
foo() = new()
end
And now when you have:
julia> foobar = foo()
foo(#undef, #undef, #undef)
Of course before accessing fields of foobar
you have to assign some value to it.
You can check if field of foobar
is assigned using isdefined
, e.g. isdefined(foobar, :field_1)
. The only small inconvenience is that isdefined
will also work if you write something like isdefined(foobar, :field_100)
and return false
(so you have to be sure that you are checking an existing field, e.g. by using the fieldnames
function or the hasfield
function; the latter is available only in Julia 1.2)
An alternative is to define foo
in the following way:
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
(you could omit defining an inner constructor in this case)
Now you can write:
julia> foobar = foo()
foo(nothing, nothing, nothing)
The benefit of this approach is that you can safely access fields of foobar
and test for their value, e.g.:
julia> foobar.file_1 === nothing
true
EDIT
Returning to your original question from another angle there is a devnull
variable that discards all data written to it. However its type is Base.DevNull
which is a subtype of IO
. Therefore, you could also write:
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
In this way you can write to file_1
, file_2
and file_3
all the time and by default what you write is discarded.
Upvotes: 3
Reputation: 452
I found out I can make an empty IOStream ans edit it late so that it would look something like this:
foobar = foo(IOStream(string()),IOStream(string()),IOStream(string()))
Upvotes: 0