未在函数主体中指定泛型类型参数时,该如何访问? [英] How can I access a generic type parameter when it hasn't been specified in the function body?
问题描述
假设我有
struct X{T} end
和在X
上进行的函数分派,如果未在方法签名中指定T
,该如何在函数体内访问T
?即
and a function dispatching on X
, how can I access T
inside the function body if it hasn't been specified in the method signature? I.e.
function foo(x::X)
# can i get T in here?
end
这是对julialang闲置问题的改写: https://julialang.slack .com/archives/C6A044SQH/p1568651904113000
要获取访问权限,只需填写以下表格: https://slackinvite.julialang.org
To get access, simply fill this form: https://slackinvite.julialang.org
推荐答案
最好的方法是定义访问器函数:
The best way to go about this is to define an accessor function:
getparam(::X{T}) where {T} = T
然后一个人可以做
function foo(x::X)
T = getparam(x)
...
end
只要您没有通过解释器运行julia,就应该在编译时消除所有类型检查.例如:
So long as you are not running julia through an interpreter, all the type checks should be elided away at compile time. For instance:
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
替换,而完全没有运行时开销.
As you may be able to see, the compiler was able to figure out that it can just replace the call foo(X{2})
with 3
at compile time with no runtime overhead at all.
作为旁注,这应该有助于说明为什么类型稳定性很重要.如果我们做过类似foo(X{rand(Int)})
的操作,则编译器将无法访问类型参数,直到它在运行时到达foo
为止,然后需要为最终评估为的任何rand(Int)
编译特定方法.会很慢:
As a side note, this should serve to demonstrate why type stability is important. If we had done something like foo(X{rand(Int)})
, the compiler wouldn't have access to the type parameter until it arrives at foo
in runtime and then would need to compile a specific method for whatever rand(Int)
ended up evaluating to, which would be very slow:
julia> @btime foo(X{rand(Int)}())
2.305 ms (1962 allocations: 125.49 KiB)
-3712756042116422157
哎呀,那真是太臭了!为了比较,
Oof, that is slooooow! For comparison,
julia> bar(x) = x + 1
bar (generic function with 1 method)
julia> @btime bar(rand(Int))
9.746 ns (0 allocations: 0 bytes)
5990190339309662951
这篇关于未在函数主体中指定泛型类型参数时,该如何访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!