Если вы хотите разрешить создание неинициализированного 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_1
, file_2
и file_3
все время и по умолчанию то, что вы пишете, отбрасывается.