要清楚的是,我不是Julia内核的铁杆用户。下面的答案旨在(希望)为非核心用户直观地解释Julia中的函数。我确实认为这个(非常好的)问题也可以从一个更为核心的语言开发人员提供的更具技术性的答案中获益。而且,这个答案比我想的要长,但我用了多个例子来尝试让事情尽可能直观。
function
它本身是一个保留关键字,不是一个实际的函数
,与实际问题正交。这个答案是为了解决你的编辑问题。
自从Julia v0.6+,
Function
是一个抽象的超类型,与
Number
是抽象超类型。所有功能,例如。
mean
、用户定义函数和匿名函数是
功能
,以同样的方式
Float64
和
Int
.
Base
. 看到了吗
here
和
here
作为起点,如果你想了解更多。
f1(f::T, x) where {T<:typeof(mean)} = f(x)
f1(f::T, x) where {T<:typeof(sum)} = f(x) + 1
函数有不同的调度方法吗
f1
既然如此,为什么。
typeof(sum)
返回
类型(总和)
typeof(Float64)
退货
DataType
? 这里的问题是,粗略地说,从句法的角度来看,
sum
需要同时为两个目的服务。它需要同时是一个值,比如。
1.0
对某些输入起作用。但是,它也需要是一个类型名,比如
.
显然,它不能同时做到这两个。所以呢
总和
f = sum ; f(randn(5))
看看它的行为如何像一个值。但我们也需要一些方法来表示
这不仅适用于
总和
因此你观察到的行为。同样,如果我写
f1(x) = x ; typeof(f1)
,也将返回
typeof(f1)
匿名函数有点棘手,因为它们没有这样命名。我们该怎么办
typeof(x -> x^2)
? 实际情况是,当您构建匿名函数时,它将作为临时全局变量存储在模块中
Main
,并给定一个用作其查找类型的数字。所以如果你写信
f = (x -> x^2)
#3 (generic function with 1 method)
,和
typeof(f)
getfield(Main, Symbol("##3#4"))
,在那里你可以看到
Symbol("##3#4")
此匿名函数的临时类型存储在
主要
. (这样做的一个副作用是,如果您编写的代码不断地任意生成相同的匿名函数,那么最终会导致内存溢出,因为它们实际上都是作为各自类型的单独全局变量存储的—然而,这确实存在
不
阻止你做这种事
for n = 1:largenumber ; findall(y -> y > 1.0, x) ; end
功能
typeof(sum) <: Function
true
,又名
类型(总和)
功能
. 还要注意
typeof(typeof(sum))
退货
,与
typeof(typeof(1.0))
退货
数据类型
,这说明
总和
实际上表现得像一个值。
现在,考虑到我所说的一切,你问题中的所有例子现在都有意义了。
typeof(function)
和
typeof(for)
返回应该返回的错误,因为
和
for
typeof(typeof)
和
typeof(in)
typeof(typeof)
,和
类型(英寸)
typeof
in
都是函数。当然要注意
typeof(typeof(typeof))
退货
数据类型