Есть ли в Юлии какой-то ноль IOStream? - PullRequest
0 голосов
/ 30 апреля 2019

В модуле 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 ]

2 голосов
/ 30 апреля 2019

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

0 голосов
/ 30 апреля 2019

Я обнаружил, что могу создать пустой IOStream и отредактировать его поздно, чтобы он выглядел примерно так:

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