在Julia中,无参数但带有类型的函数。

4
我最近查看了一些Julia的源代码,发现其中一些函数对我来说似乎很神秘。
在Julia源代码中定义了一些没有参数但有类型注释的函数。
例如:在abstractarray.jl的第20行中。
我稍微尝试了一下ndims函数,
它似乎可以将类型本身作为参数并返回正确的值:
julia> ndims(AbstractArray{Float64, 2})
       2
julia> ndims([1.1 0.3; 0. 0.5])
       2

有人能解释一下方法中的 (::DataType) 是如何工作的吗?或者在Julia中它是什么意思?
1个回答

13
当探索Julia中函数的行为时,了解调用的具体方法非常重要。Julia是围绕多重分发组织的,因此单个名称(例如ndims)可以与不同的实现相关联--由参数的类型选择。要查看ndims的实现方式,我们可以使用@which宏来确定特定调用所选择的实现。
julia> @which ndims(AbstractArray{Float64, 2})
ndims{T,n}(::Type{AbstractArray{T,n}}) at abstractarray.jl:61

julia> @which ndims([1.1 0.3; 0. 0.5])
ndims{T,n}(::AbstractArray{T,n}) at abstractarray.jl:60

abstractarray.jl 中当前的实现如下:

ndims{T,n}(::AbstractArray{T,n}) = n
ndims{T,n}(::Type{AbstractArray{T,n}}) = n

两个签名都是参数化方法,需要参数{T,n}

  • 第一个签名适用于类型为AbstractArray{T,n}实例 - 例如,在您的示例中,[1.1 0.3; 0. 0.5](在几个抽象层之下)。
  • 第二个签名适用于AbstractArray{T,n}本身的类型

(两个签名都没有命名参数,尽管它们显然都接受一个参数。因为行为仅取决于参数的类型签名,所以不需要名称)

相关概念在Julia手册的类型方法部分有解释。


哎呀...我忘记使用@which来确保调用了哪个方法。 实际上,为了简化我的问题,我只想知道如果我将Array的实例的ndims定义为ndims(arr::AbstractArray{T, n}) = n而不是源代码中发现的ndims(::AbstractArray{T, n}) = n,有什么区别。 - DboyLiao
3
没有区别 -- 第二个版本仍然接受一个参数,只是这个参数没有名称。这是因为函数完全依赖于参数化。{T,n} 在某种意义上也是“参数”,但是在类型系统的层面上。如果你需要实际操作 arr,那么当然必须像第一个版本一样给参数命名。 - Isaiah Norton
谢谢。这就是我要找的答案。 - DboyLiao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接