我typeof对Julia 1.0.0 REPL中的以下结果感到困惑:
# 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 ")"
Run Code Online (Sandbox Code Playgroud)
Julia 1.0.0 文档说typeof
"获取具体类型的x".
这个typeof(function)例子让我很惊讶.我期望function在Julia中成为一流的对象并拥有一个类型.我想我需要了解朱莉娅的类型.
有什么建议?
编辑
根据下面的一些评论问题,这里是一个基于小函数的示例:
julia> function test() return "test"; end
test (generic function with 1 method)
julia> test()
"test"
julia> typeof(test)
typeof(test)
Run Code Online (Sandbox Code Playgroud)
根据这个例子,我本来希望typeof(test)回来generic function,而不是typeof(test).
要明确的是,我不是朱莉娅内部的核心用户.以下是一个答案,旨在(希望)直观地解释Julia为非核心用户提供的功能.我认为这个(非常好的)问题也可以从该语言的一个更核心的开发者提供的更技术性的答案中受益.此外,这个答案比我想要的还要长,但我已经使用了多个例子来尝试让事情尽可能直观.
正如在评论中指出的那样,function它本身是一个保留关键字,并不是一个实际的函数本身,因此与实际问题正交.此答案旨在解决您对问题的编辑问题.
由于朱莉娅v0.6 +,Function是一个抽象的超类型,与抽象超类型的方式大致相同Number.所有函数(例如mean,用户定义的函数和匿名函数)都是其子类型的子类型Function,Float64并且Int是子类型的子类型Number.
这种结构是有意的并且具有几个优点.
首先,由于我不完全理解的原因,以这种方式构造函数是允许Julia中的匿名函数运行与内置函数一样快的关键Base.如果您想了解更多相关信息,请参阅此处和此处作为起点.
其次,因为每个函数都是自己的子类型,所以现在可以调度特定的函数.例如:
f1(f::T, x) where {T<:typeof(mean)} = f(x)
Run Code Online (Sandbox Code Playgroud)
和:
f1(f::T, x) where {T<:typeof(sum)} = f(x) + 1
Run Code Online (Sandbox Code Playgroud)
是函数的不同调度方法 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)和function有保留的语法.for并typeof(typeof)正确地返回(分别)typeof(in),和typeof(typeof),因为typeof(in)和typeof都是功能.注意当然会in返回typeof(typeof(typeof)).
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |