我想在不评估函数的情况下在Julia中获取函数调用的结果类型,并使用该类型。所需用法如下所示:
foo(x::Int32) = x
foo(x::Float32) = x
y = 0.0f0
# Assert that y has the type of result of foo(Float32)
y::@resultof foo(Float32) # This apparently does not work in Julia
Run Code Online (Sandbox Code Playgroud)
虽然在上述情况下,我可以简单地使用y::typeof(foo(1.0f0))虚拟变量的评估,但在更复杂的情况下,初始化虚拟变量可能会带来不便和昂贵。例如,我想使用function返回的迭代器类型eachline(filename::AbstractString; keep::Bool=false),但是使用typeoftrue确实需要成功打开文件,这看起来有些过头了。
从C ++的背景来看,我要问的是std::result_of在Julia 中是否有一个等效项。问题几乎与此相同,但语言是朱莉娅。
经过一些研究,我发现Julia在一个函数中允许不同类型的返回值,其中类型推断看起来非常困难。例如,
foo(x::Int64) = x == 1 ? 1 : 1.0
Run Code Online (Sandbox Code Playgroud)
现在,返回类型可以是Int64或Float64,具体取决于输入值。不过,在这种情况下,我仍然想知道是否有一些宏技巧可以推断出返回类型为Union{ Int64, Float64 }?。
总而言之,我的问题是:
1)是,Base.return_types(foo, (Int64,))将返回一个包含您要求的返回类型的数组,Union{ Int64, Float64 }在这种情况下。如果删除第二个参数(指定输入参数类型的元组),则将获得所有可能的推断返回类型。
但是,应注意,编译器可能随时决定返回Any或返回其他任何正确但不精确的返回类型。
2)参见1)?
3)对于给定的输入参数类型,编译器将尝试在编译时推断返回类型。如果可能是多个,它将推断一个Union类型。如果它完全失败,或者返回类型太多,它将推断Any为返回类型。在后一种情况下,仅在运行时才知道实际的返回类型。
演示1):
julia> foo(x::Float32) = x
foo (generic function with 1 methods)
julia> foo(x::Int32) = x
foo (generic function with 2 methods)
julia> foo(x::Int64) = x == 1 ? 1 : 1.0
foo (generic function with 3 methods)
julia> Base.return_types(foo)
3-element Array{Any,1}:
Union{Float64, Int64}
Int32
Float32
julia> Base.return_types(foo, (Int64,))
1-element Array{Any,1}:
Union{Float64, Int64}
julia> Base.return_types(foo, (Int32,))
1-element Array{Any,1}:
Int32
Run Code Online (Sandbox Code Playgroud)