未在函数主体中指定泛型类型参数时,该如何访问? [英] How can I access a generic type parameter when it hasn't been specified in the function body?

查看:90
本文介绍了未在函数主体中指定泛型类型参数时,该如何访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

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.

作为旁注,这应该有助于说明为什么

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆