在julia中键入稳定do块

在julia中键入稳定do块,julia,type-stability,Julia,Type Stability,我想从带有do块的文件中读取数据。使用do块非常重要,因为我需要确保即使在读取文件期间发生错误,文件也能正确关闭。文件中的数据应转换为作为参数提供的a类型。我真正的用例是使用NetCDF文件,但我可以用纯文本文件重现类型稳定性问题 假设有一个文件file.txt,其内容为123,可通过以下方式创建: write("file.txt","123") 当我加载没有do块的文件时,结果是类型稳定的: function loadfile1(T) f = open("file.txt")

我想从带有do块的文件中读取数据。使用do块非常重要,因为我需要确保即使在读取文件期间发生错误,文件也能正确关闭。文件中的数据应转换为作为参数提供的a类型。我真正的用例是使用NetCDF文件,但我可以用纯文本文件重现类型稳定性问题

假设有一个文件
file.txt
,其内容为
123
,可通过以下方式创建:

 write("file.txt","123")
当我加载没有do块的文件时,结果是类型稳定的:

function loadfile1(T)
    f = open("file.txt")
    data = parse(T,readline(f))
    close(f)
    return data
end
@code\u warntype
正确地推断我得到了
Float32
,结果如下:

@code_warntype loadfile1(Float32)
Body::Float32
[...]
但是,以下变体:

function loadfile2(T)
    f = open("file.txt") do f
        return parse(T,readline(f))
    end
end
生成类型不稳定的代码:

 @code_warntype loadfile2(Float32)
Body::Any
9 1 ─ %1 = %new(getfield(Main, Symbol("##842#843")){DataType}, T)::getfield(Main, Symbol("##842#843")){DataType}                                                                                  │ 
  │   %2 = Main.open::Core.Compiler.Const(open, false)                                                                                                                                            │ 
  │   %3 = invoke Base.:(#open#294)($(QuoteNode(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}()))::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, %2::Function, %1::getfield(Main, Symbol("##842#843")){DataType}, "file.txt"::String)::Any
  └──      return %3            

如何修改函数
loadfile2
(带有do块)并仍然获得类型稳定的结果?

T
移动到签名中的类型规范是可行的:

function loadfile2(::Type{T}) where T
    f = open("file.txt") do f
        return parse(T,readline(f))
    end
end
这种方式
T
在编译时是已知的