julia - 在函数体中未指定泛型类型参数时,如何访问它?

标签 julia

假设我有

struct X{T} end

和在 X 上调度的函数,如果方法签名中未指定 T,我如何访问函数体内的 T?即

function foo(x::X)
    # can i get T in here?
end

这是对来自 julialang slack 的问题的改写:https://julialang.slack.com/archives/C6A044SQH/p1568651904113000

要获得访问权限,只需填写此表格:https://slackinvite.julialang.org

最佳答案

解决此问题的最佳方法是定义访问器函数:

getparam(::X{T}) where {T} = T

然后就可以了

function foo(x::X)
    T = getparam(x)
    ...
end

只要您不通过解释器运行 julia,所有类型检查都应该在编译时删除。例如:


julia> foo(x::X) = getparam(x) + 1
foo (generic function with 1 method)

julia> foo(X{1}())
2

julia> @code_llvm foo(X{1}())

;  @ REPL[24]:1 within `foo'
define i64 @julia_foo_19216() {
top:
  ret i64 2
}

julia> @code_llvm foo(X{2}())

;  @ REPL[24]:1 within `foo'
define i64 @julia_foo_19221() {
top:
  ret i64 3
}

正如您可能看到的那样,编译器能够弄清楚它可以在编译时将调用 foo(X{2}) 替换为 3完全没有运行时开销的时间。


作为旁注,这应该可以说明为什么 type stability很重要。如果我们做了类似 foo(X{rand(Int)}) 的操作,编译器将无法访问类型参数,直到它在运行时到达 foo 并且然后需要为任何 rand(Int) 最终评估到的内容编译一个特定的方法,这将非常慢:

julia> @btime foo(X{rand(Int)}())
  2.305 ms (1962 allocations: 125.49 KiB)
-3712756042116422157

噢,太懒了!为了比较,

julia> bar(x) = x + 1
bar (generic function with 1 method)

julia> @btime bar(rand(Int))
  9.746 ns (0 allocations: 0 bytes)
5990190339309662951

关于julia - 在函数体中未指定泛型类型参数时,如何访问它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57962169/

相关文章:

Julia Matrix{AbstractFloat} 类型问题

dictionary - julia 0.6 中不同类型字典的向量

Julia 相当于 R 的帮助页面和小插曲?

for-loop - Julia 中并行 for 循环中的数据管理

julia - NLopt SLSQP 放弃了好的解决方案,取而代之的是旧的、更差的解决方案

julia - 如何向 map 切片中的引用函数添加额外的(静态)输入参数?

multidimensional-array - Julia 在所需尺寸上点积的方法是什么

julia - 函数 Base.+ 必须显式导入才能扩展

types - Julia 自定义类型分配

julia - 如何在 julia 中捕获 linux 信号