gpt4 book ai didi

julia - Julia typeof的令人困惑的结果

转载 作者:行者123 更新时间:2023-12-04 16:57:36 24 4
gpt4 key购买 nike

我对Julia 1.0.0 REPL中typeof的以下结果感到困惑:

# This makes sense.   
julia> typeof(10)
Int64

# This surprised me.
julia> typeof(function)
ERROR: syntax: unexpected ")"

# No answer at all for return example and no error either.
julia> typeof(return)

# In the next two examples the REPL returns the input code.
julia> typeof(in)
typeof(in)

julia> typeof(typeof)
typeof(typeof)

# The "for" word returns an error like the "function" word.
julia> typeof(for)
ERROR: syntax: unexpected ")"

朱莉娅1.0.0 documentation表示 typeof “获取x的具体类型。”
typeof(function)示例使我感到非常惊讶。我期望 function是Julia中的一流对象,并且具有类型。我想我需要了解Julia中的类型。

有什么建议么?

编辑

根据下面的一些注释问题,这是一个基于小功能的示例:
julia> function test() return "test"; end
test (generic function with 1 method)

julia> test()
"test"

julia> typeof(test)
typeof(test)

基于此示例,我希望 typeof(test)返回 generic function,而不是 typeof(test)

最佳答案

需要明确的是,我不是Julia内部构造的硬核用户。以下是一个答案,旨在(希望)直观地解释非核心用户的Julia中的功能。我确实认为,这个(非常好)问题也可以从该语言的更多核心开发人员之一提供的更具技术性的答案中受益。另外,这个答案比我想要的要长,但是我使用了多个示例来尝试使事情尽可能直观。

正如评论中指出的那样,function本身是一个保留关键字,本身并不是一个实际的函数,因此与实际的问题正交。该答案旨在解决您对该问题的编辑。

从Julia v0.6 +开始,Function是抽象超型,与Number是抽象超型非常相似。所有功能,例如mean(用户定义函数和匿名函数)是Function的子类型,就像Float64IntNumber的子类型一样。

这种结构是经过精心设计的,具有多个优点。

首先,出于我不完全理解的原因,以这种方式构造函数是允许Julia中的匿名函数与Base的内置函数一样快地运行的关键。如果要了解更多信息,请参阅herehere作为起点。

其次,由于每个函数都是其自己的子类型,因此您现在可以分派(dispatch)特定的函数。例如:

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(sum),尤其是考虑到 typeof(Float64)返回 DataType吗?这里的问题是,从语法的角度来看,大致来说, sum需要同时满足两个目的。它必须既是一个值,例如 1.0,尽管它用于在某些输入上调用 sum函数。但是,它也需要是类型名称,例如 Float64

显然,它不能同时做这两个事情。因此, sum本身的行为就像一个值。您可以编写 f = sum ; f(randn(5))来查看其行为如何像一个值。但是我们还需要一种表示 sum类型的方法,这种类型不仅适用于 sum,而且适用于任何用户定义的函数和任何匿名函数。开发人员决定采用(可能是最简单的)选项,并将 sum的类型从字面上显示为 typeof(sum),因此您会观察到这种行为。同样,如果我编写 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")是此匿名函数存储在 Main中的临时类型。 (这样做的副作用是,如果您编写的代码不断地反复任意生成相同的匿名函数,最终将导致内存溢出,因为它们实际上都存储为各自类型的单独全局变量-但是,这不会阻止您在函数内执行类似 for n = 1:largenumber ; findall(y -> y > 1.0, x) ; end的操作,因为在这种情况下,匿名函数在编译时仅被编译一次。

将所有这些都与 Function父类型相关联,您会注意到 typeof(sum) <: Function返回 true,表明 sum的类型(也称为 typeof(sum))确实是 Function的子类型。还要注意, typeof(typeof(sum))返回 DataType,与 typeof(typeof(1.0))返回 DataType的方式几乎相同,这表明 sum实际上如何表现为值。

现在,考虑到我所说的一切,您问题中的所有示例现在都说得通了。 typeof(function)typeof(for)返回错误,因为 functionfor是保留语法。 typeof(typeof)typeof(in)分别正确返回 typeof(typeof)typeof(in),因为 typeofin都是函数。当然,请注意 typeof(typeof(typeof))返回 DataType

关于julia - Julia typeof的令人困惑的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52351852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com