主要设施
导言
Julia Base模块包含许多适用于执行科学和数值计算的函数和宏,但它并不逊色于许多通用编程语言。 其他功能可以在扩展集合中找到。 https://julialang.org/packages /[可用的软件包]。 这些功能按以下主题分组。
一些一般的注意事项。
-
要应用模块的功能,请使用"导入模块"导入模块和"模块"。fn(x)'来使用函数。
-
或者,'using Module`将所有导出的`Module’函数导入当前命名空间。
-
按照惯例,函数名以感叹号('!')改变他们的论点。 有些函数有两个可变的(例如,
排序!
)和不可变(`排序')版本。
"基础"和标准库的行为是稳定的,如https://semver.org /[SemVer],只有当它被记录,即包含在https://docs.julialang.org /[Julia文档]并且没有标记为不稳定。 有关更多信息,请参阅页面 API问题和答案。
一般资料
# '基。退出'-Function
exit(code=0)
停止程序并返回退出代码。 默认退出代码为零。 这意味着程序已成功完成。 在交互式会话期间,可以使用键盘快捷键`^D`调用’exit()'函数。
# '基。atexit'-Function
atexit(f)
注册不带参数或带有一个参数的函数`f()',在退出进程时调用。 `Atexit()'拦截器按LIFO顺序调用(上次接收-首次服务),并在对象终结器之前执行。
如果’f’有一个为单个整数参数定义的方法,它将被称为`f(n::Int32)`,其中`n`是当前退出代码,否则将被称为`f()'。
兼容性:Julia1.9
单参数形式需要Julia1.9。 |
出口拦截器可以调用’exit(n)。 在这种情况下,Julia以退出代码`n
(而不是原始退出代码)终止执行。 如果`exit(n)`函数被多个退出拦截器调用,Julia将使用与调用`exit(n)'的最后一个退出拦截器对应的退出代码终止执行。 (由于退出拦截器是按LIFO顺序调用的,因此最后一个调用者将是第一个注册的拦截器。)
注意。 调用所有出口拦截器后,不能再注册任何出口拦截器,并且在所有拦截器完成后对`atexit(f)`的任何调用都将导致异常。 当拦截器注册用于退出在关闭期间可能仍然并行运行的后台任务时,可能会出现这种情况。
# '基。summarysize'-Function
Base.summarysize(obj; exclude=Union{...}, chargeall=Union{...}) -> Int
计算参数中可用的所有唯一对象所占用的内存量(以字节为单位)。
命名参数
-
'exclude':从爬网中排除的对象类型。
-
'chargeall':总是考虑所有字段大小的对象类型,即使它们通常被排除在外。
另请参阅说明 'sizeof'。
例子
julia> Base.summarysize(1.0)
8
julia> Base.summarysize(Ref(rand(100)))
848
julia> sizeof(Ref(rand(100)))
8
# '基。__预编译__`-Function
__precompile__(isprecompilable::Bool)
确定调用此函数的文件是否可以预编译。 默认值为’true'。 如果预编译模块或文件不安全,请调用'__precompile__(false)',以便在Julia中尝试预编译时发生错误。
# '基。包括'-Function
Base.include([mapexpr::Function,] m::Module, path::AbstractString)
在模块`m’的全局范围内计算输入源代码文件的内容。 对于每个模块(使用关键字声明的模块除外 'baremodule')有自己的`include`函数的定义,没有’m’参数,它计算该模块中文件的内容。 返回输入文件中最后一个计算表达式的结果。 在激活期间,包含文件的目录的路径被设置为任务的本地激活路径。 通过对`include`函数的嵌套调用,相对于此路径执行搜索。 此功能通常用于以交互方式下载源代码或将文件合并到拆分为多个源代码文件的包中。
使用可选的第一个参数’mapexpr`,您可以在计算之前转换包含的代码:对于’path’中的每个分析表达式’expr`,'include’函数实际上计算’mapexpr(expr)'。 如果未指定`mapexpr’参数,则默认为 '身份'。
兼容性:Julia1.5
Julia1.5版本需要传递’mapexpr’参数。 |
# `include'-Function
include([mapexpr::Function,] path::AbstractString)
计算包含模块全局区域中输入源代码文件的内容。 每个模块(除了用关键字`baremodule’声明的模块)都有自己的`include`函数定义,该函数计算该模块中文件的内容。 返回输入文件中最后一个计算表达式的结果。 在激活期间,包含文件的目录的路径被设置为任务的本地激活路径。 通过对`include`函数的嵌套调用,相对于此路径执行搜索。 此功能通常用于以交互方式下载源代码或将文件合并到拆分为多个源代码文件的包中。 'Path’参数使用函数进行规范化 normpath'
,它解析相对路径字符,如。.并将
/'转换为适当的路径分隔符。
使用可选的第一个参数’mapexpr`,您可以在计算之前转换包含的代码:对于’path’中的每个分析表达式’expr`,'include’函数实际上计算’mapexpr(expr)'。 如果未指定`mapexpr’参数,则默认为 '身份'。
要计算另一个模块中的文件内容,请使用 '基地。包括'。
兼容性:Julia1.5
Julia1.5版本需要传递’mapexpr’参数。 |
# '基。include_string'-Function
include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")
它的作用方式与 'include',但从指定的字符串中读取代码,而不是从文件中读取代码。
使用可选的第一个参数’mapexpr`,您可以在计算之前转换包含的代码:对于’code’中的每个分析表达式’expr`,函数`include_string’实际上计算’mapexpr(expr)'。 如果未指定`mapexpr’参数,则默认为 '身份'。
兼容性:Julia1.5
Julia1.5版本需要传递’mapexpr’参数。 |
# '基。include_dependency'-Function
include_dependency(path::AbstractString; track_content::Bool=true)
在模块中声明`path`参数中指定的文件,目录或符号链接(作为相对或绝对路径)是预编译的依赖项。 这意味着使用’track_content=true`,如果`path`的内容发生变化(如果`path`是目录,则内容将是`join(readdir(path))'),则需要重新编译模块。 使用’track_content=false`,如果`path`的修改时间`mtime’发生变化,则会触发重新编译。
只有当模块依赖于不被使用的路径时,才需要 '包括'。 它仅在编译期间有效。
兼容性:Julia1.11
要使用命名的’track_content’参数,需要Julia至少1.11的版本。 如果无法读取"路径",则返回错误。 |
#
'__init__
*-Keyword
__init__
模块中的函数`__init__()在执行过程中第一次加载模块后立即执行。 它在执行模块中的所有其他语句后被调用一次。 由于它是在模块完全导入后调用的,因此
__init__+`+'子模块的功能将首先执行。 `Init+`+'函数的两个典型用法是调用外部C库的运行时初始化函数和初始化全局常量,这些常量使用外部库返回的指针。 有关详细信息,请参阅 手册的模块部分。
例子
const foo_data_ptr = Ref{Ptr{Cvoid}}(0)
function __init__()
ccall((:foo_init, :libfoo), Cvoid, ())
foo_data_ptr[] = ccall((:foo_data, :libfoo), Ptr{Cvoid}, ())
nothing
end
# '基。哪个`-Method
which(f, types)
返回`F`参数的方法(`Method`对象),它将被调用为`types`类型的参数。
如果’types’是抽象类型,则返回将由`invoke`函数调用的方法。
另请参阅说明 'parentmodule`, '@which'和 '@编辑'。
# '基。方法'-Function
methods(f, [types], [module])
返回`f`的方法表。
如果指定了’types’参数,则返回相应类型的方法数组。 如果指定了’module’参数,则返回此模块中定义的方法数组。 您还可以将模块列表指定为数组。
兼容性:Julia1.4
要指定模块,需要至少1.4的Julia版本。 |
另请参阅说明 '哪个`, '@which'和 'methodswith'。
# '基。set_active_project'-Function
set_active_project(projfile::Union{AbstractString,Nothing})
将`projfile’中指定的文件设置为活动的’项目。toml’档案。 另请参阅说明 '基地。active_project'。
兼容性:Julia1.8
此功能需要至少1.8的Julia版本。 |
关键词
下面是Julia中的保留关键字列表。 baremodule
,begin
,break
,catch
,const
,continue
,do
,else
,elseif
,end
,export
,false
,finally
,for
,function
,global
,if
,import
,let
,local
,macro
,module
,quote
,return
,struct
,true
,try
,using
,`while'。 禁止使用这些关键字作为变量名。
以下两个字序列也被保留’抽象类型','可变结构','原始类型'。 但是,您可以创建名为:abstract
,mutable
,`primitive`和`type’的变量。
最后:'where’被分析为中缀运算符,用于编写参数化方法和类型的定义’in’和`isa’被分析为中缀运算符;`public`被分析为顶级运算符开头的关键字;`outer’被分析为关键字,当 但是,允许创建名为`where`,in
,isa
,`outer`和`as’的变量。
# ’模块'*-Keyword
module
关键字’module’声明一个对象 'Module'--一个单独的全局变量工作区。 在模块内部,您可以使其他模块的名称可见(通过导入)或使此模块的名称公开可用(通过"导出"和"公开")。 模块允许您创建顶级定义,而不必担心当您的代码与其他人的代码一起使用时名称冲突。有关更多信息,请参阅 手册的模块部分。
例子
module Foo
import Base.show
export MyType, foo
struct MyType
x
end
bar(x) = 2x
foo(a::MyType) = bar(a.x) + 1
show(io::IO, a::MyType) = print(io, "MyType $(a.x)")
end
# ’使用'*-Keyword
using
'using Foo’加载模块或包’Foo’并使用关键字导出其名称 '出口',可直接使用。 名称也可以使用点符号来引用(例如,Foo.foo’来访问名称’foo
),无论它们是否使用`export’导出。 有关详细信息,请参阅 手册的模块部分。
如果两个或多个包/模块导出一个名称,而这个名称在每个包中没有引用同一个对象,并且这些包是通过"使用"加载的,而没有明确的名称列表,那么引用这个名称而不指定它是一个错误。 因此,建议设计为与其依赖项和Julia的未来版本进一步兼容的代码,例如发布包中的代码,从每个下载的包中指定它使用的名称,例如`using Foo:Foo,f`而不是`using Foo'。 |
# `as'-Keyword
as
'as’用作关键字,用于重命名使用`import`或`using’添加到作用域的标识符。 这对于解决名称冲突以及缩短名称非常有用。 (在`import`或’using''as’运算符之外,它不是关键字,可以用作常规标识符。)
'import LinearAlgebra as LA`将导入的标准库’LinearAlgebra’引入范围为’LA'。
'import LinearAlgebra:eigen as eig,cholesky as chol`将`LinearAlgebra`中的`eigen`和`cholesky`方法分别引入`eig`和`chol’范围。
只有在作用域中输入单独的标识符时,`as`关键字才与`using’运算符配合使用。 例如,`using LinearAlgebra:eigen as eig’或`using LinearAlgebra:eigen as eig,cholesky as chol`将起作用,但`using LinearAlgebra as LA`是一种无效的语法,因为将所有从`LinearAlgebra`导出的名称重命名为`LA`没有意义。
# ’macro'*-Keyword
macro
关键字"宏"定义了将生成的代码插入程序的方法。 宏将作为参数传递的表达式序列与返回的表达式进行匹配。 生成的表达式被插入到调用宏的地方的程序中。 宏允许您在不调用的情况下执行生成的代码 eval'
:生成的代码只是成为周围程序的一部分。 宏参数可以是表达式、字面值和符号。 宏可以用可变数量的参数(varargs)定义,但它们不接受命名参数。 包含行号的参数__source__,宏被调用的文件名,以及包含宏被扩展的模块的参数
_module__`也隐式传递给每个宏。
有关编写宏的更多信息,请参阅手册上的部分 元编程。
例子
julia> macro sayhello(name)
return :( println("Hello, ", $name, "!") )
end
@sayhello (macro with 1 method)
julia> @sayhello "Charlie"
Hello, Charlie!
julia> macro saylots(x...)
return :( println("Say: ", $(x...)) )
end
@saylots (macro with 1 method)
julia> @saylots "hey " "there " "friend"
Say: hey there friend
# ’返回'*-Keyword
return
'Return x’运算符导致函数的早期退出,并将`x’的值传递给调用者。 没有值的关键字’return’等同于’return nothing'(请参阅说明 `无')。
function compare(a, b)
a == b && return "equal to"
a < b ? "less than" : "greater than"
end
通常,'return’运算符可以放在函数体的任何位置,包括深度嵌套的循环或条件语句中,但要小心’do`块。 例如:
function test1(xs)
for x in xs
iseven(x) && return 2x
end
end
function test2(xs)
map(xs) do x
iseven(x) && return 2x
x
end
end
在第一个例子中,return语句在遇到偶数时立即终止`test1`函数的执行,因此调用`test1([5,6,7])返回`12
。
在第二个例子中,人们会期望同样的事情,但实际上,在这种情况下,return`运算符退出内部函数(在`do`块内)并返回`map`函数的值。 因此,调用’test2([5,6,7])`返回
[5,12,7]`。
当在顶级表达式中使用时(即在函数外部),`return`运算符会导致整个当前顶级表达式过早终止。
# ``do'*-Keyword
do
创建一个匿名函数并将其作为第一个参数传递给函数调用。 例如:
map(1:10) do x
2x
end
它相当于'map(x->2x,1:10)`。
您可以使用多个参数,如下所示。
map(1:10, 11:20) do x, y
x + y
end
# `begin'-Keyword
begin
关键字'开始。..end'表示一个代码块。
begin
println("Hello, ")
println("World!")
end
关键字’begin’也可用于索引。 在这种情况下,它意味着数组的集合或维度的第一个索引。 例如``a[begin]`是数组’a’的第一个元素。
兼容性:Julia1.4
要使用`begin’作为索引,需要至少1.4的Julia版本。 |
例子
julia> A = [1 2; 3 4]
2×2 Array{Int64,2}:
1 2
3 4
julia> A[begin, :]
2-element Array{Int64,1}:
1
2
# ``let'*-Keyword
let
"Let"块创建一个严格的范围,并额外引入新的本地绑定。
作为和 其他范围构造,`let’块定义了一个代码块,其中表示的局部变量将可用。 此外,这种语法对于逗号分隔的赋值和变量名特别重要,它们可以选择与`let`位于同一行。:
let var1 = value1, var2, var3 = value3
code
end
此行中呈现的变量是"let"块的本地变量,并且分配按顺序计算,每个右侧都在范围内计算,而不考虑左侧的名称。 出于这个原因,表达式’let x=x’将是有意义的,因为左侧和右侧部分中的`x`是不同的变量,左侧部分从外部区域局部遮蔽了`x`。 这甚至可能是有用的,因为新的局部变量在每次进入局部区域时都会重新创建,但是这只有在变量由于闭包而继续存在于其区域之外时才会表现出来。 没有赋值的表达式’let`(如上例中的’var2')声明了一个尚未绑定到值的新局部变量。
相比之下,块 'begin'也将几个表达式组合在一起,但没有引入作用域,也没有特殊的赋值语法。
例子
在下面的函数中,有一个`x`使用`map`迭代更新三次。 所有返回的闭包在其最终值中都引用了这个’x'。:
julia> function test_outer_x()
x = 0
map(1:3) do _
x += 1
return ()->x
end
end
test_outer_x (generic function with 1 method)
julia> [f() for f in test_outer_x()]
3-element Vector{Int64}:
3
3
3
但是,如果我们添加一个引入新局部变量的`let`块,我们最终会得到三个不同的变量(每次迭代中一个),即使我们决定使用(阴影)相同的名称。
julia> function test_let_x()
x = 0
map(1:3) do _
x += 1
let x = x
return ()->x
end
end
end
test_let_x (generic function with 1 method)
julia> [f() for f in test_let_x()]
3-element Vector{Int64}:
1
2
3
所有引入新局部变量的作用域构造在多次运行时的行为方式类似。 "Let"的一个显着特点是它能够简洁地声明新的局部变量("local"),这些变量可以以不同的方式掩盖外部变量。 例如,直接使用函数参数"do"类似地记录三个不同的变量。:
julia> function test_do_x()
map(1:3) do x
return ()->x
end
end
test_do_x (generic function with 1 method)
julia> [f() for f in test_do_x()]
3-element Vector{Int64}:
1
2
3
# 'if'-Keyword
if/elseif/else
'If'/elseif
/else’构造允许您执行条件计算:根据布尔表达式的值计算或不计算代码的部分。 条件构造`if
/elseif
/`else`的语法排列如下。
if x < y
println("x is less than y")
elseif x > y
println("x is greater than y")
else
println("x is equal to y")
end
如果条件表达式’x<y’为真,则计算相应的块;否则,计算条件表达式`x>y`,如果为真,则计算相应的块。 如果表达式都不为true,则计算’else’块。 "Elseif"和"else"块是可选的。 可以有任意数量的"elseif"块。
与其他一些语言不同,条件必须是`Bool’类型。 将条件转换为`Bool`的能力是不够的。
julia> if 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context
# `while'-Keyword
while
'While’循环允许您重新计算条件表达式,并继续计算while循环的主体,直到表达式为true。 如果条件表达式在第一次求值时为false,则永远不会求值循环体。
例子
julia> i = 1
1
julia> while i < 5
println(i)
global i += 1
end
1
2
3
4
# ’break'*-Keyword
break
执行从循环的立即退出。
例子
julia> i = 0
0
julia> while true
global i += 1
i > 5 && break
println(i)
end
1
2
3
4
5
# ``continue'*-Keyword
continue
跳过循环当前迭代的其余部分。
例子
julia> for i = 1:6
iseven(i) && continue
println(i)
end
1
3
5
# 'try'-Keyword
try/catch
'Try'/`catch’运算符允许您拦截由函数引起的错误(异常 'throw'这样程序可以继续执行。 例如,在下面的代码中,尝试写入文件,但如果无法写入文件,用户会收到警告并继续执行。:
try
open("/danger", "w") do f
println(f, "Hello")
end
catch
@warn "Could not write file."
end
或者如果文件无法读取到变量中:
lines = try
open("/danger", "r") do f
readlines(f)
end
catch
@warn "File not found."
end
使用语法`catch e`(其中’e’是任何变量),触发异常的对象被分配给`catch`块中的指定变量。
"Try"/"catch"结构非常有用,因为它允许您立即将深度嵌套的计算转移到调用函数堆栈中更高的级别。
# ’local'*-Keyword
local
关键字’local’声明一个新的局部变量。 有关详细信息,请参阅 手册中有关变量作用域的部分。
例子
julia> function foo(n)
x = 0
for i = 1:n
local x # объявить локальную для цикла переменную x
x = i
end
x
end
foo (generic function with 1 method)
julia> foo(10)
0
# 'global'-Keyword
global
当使用表达式’global x`时,当前作用域及其内部作用域中的变量`x’开始引用具有相同名称的全局变量。 有关详细信息,请参阅 手册中关于变量作用域的部分。
例子
julia> z = 3
3
julia> function foo()
global z = 6 # использовать переменную z, определенную вне foo
end
foo (generic function with 1 method)
julia> foo()
6
julia> z
6
# ’outer'*-Keyword
for outer
在’for`循环中重用现有的局部变量进行迭代。
有关详细信息,请参阅 手册中有关变量作用域的部分。
另请参阅说明 '为'。
例子
julia> function f()
i = 0
for i = 1:3
# пусто
end
return i
end;
julia> f()
0
julia> function f()
i = 0
for outer i = 1:3
# пусто
end
return i
end;
julia> f()
3
julia> i = 0 # глобальная переменная
for outer i = 1:3
end
ERROR: syntax: no outer local variable declaration exists for "for outer"
[...]
# ’const'*-Keyword
const
关键字’const’用于声明值不会更改的全局变量。 几乎总是(特别是在性能要求很高的代码中),全局变量应该以这种方式声明为常量。
const x = 5
可以在单个`const`表达式中声明多个变量。:
const y, z = 7, 11
请注意,'const’仅适用于一个操作'=`,因此表达式`const x=y=1`仅声明变量`x`为常量,而不是`y'。 反过来,表达式’const x=const y=1`将`x`和`y’声明为常量。
请注意,"恒定性"不适用于可变容器;只有变量与其值之间的关系是不可变的。 例如,如果’x’是一个数组或字典,它的元素仍然可以被修改,添加或删除。
在某些情况下,当更改声明为’const’的变量的值时,会发出警告,而不是错误。 然而,这会使程序不可预测或损坏其状态,因此应该避免这种情况。 此功能仅用于交互式工作时的方便。
# ’struct'*-Keyword
struct
Julia中最广泛使用的类型是结构。 它的定义由一个名称和一组字段组成。
struct Point
x
y
end
字段可以具有可以参数化的类型约束。:
struct Point{X}
x::X
y::Float64
end
抽象超类型也可以使用语法'<:`在结构中声明:
struct Point <: AbstractPoint
x
y
end
默认情况下,'struct’实例是不可变的:它们在创建后不能更改。 但是,使用关键字 '可变结构'您可以声明一个实例可以被修改的类型。
在手册中专门用于 复合类型,提供了额外的信息,例如,关于构造函数的定义。
# '基。@kwdef'-Macro
@kwdef typedef
这是一个辅助宏,它根据表达式`typedef’中声明的类型的关键字自动确定构造函数,该关键字应该是表达式’struct’或’mutable struct'。 默认参数是在声明像`field::T=default`或`field=default’这样的字段时指定的。 如果未指定默认值,则命名参数将成为结果类型的构造函数中的强制命名参数。
仍然可以定义内部构造函数,但其中至少有一个必须接受与默认内部构造函数形式相同的参数(即,每个字段一个位置参数),以便与外部关键字构造函数正
兼容性:Julia1.1
为’基地。@kwdef’对于参数化结构和具有超类型的结构,需要Julia版本1.1或更高版本。 |
兼容性:Julia1.9
此宏自Julia1.9版本开始导出。 |
例子
julia> @kwdef struct Foo
a::Int = 1 # указанное значение по умолчанию
b::String # требуемое ключевое слово
end
Foo
julia> Foo(b="hi")
Foo(1, "hi")
julia> Foo()
ERROR: UndefKeywordError: keyword argument `b` not assigned
Stacktrace:
[...]
# 'where'-Keyword
where
关键字’where’创建类型 'unionAll',它可以表示为某个变量的所有值的其他类型的可迭代联合。 例如,类型'Vector{T} 其中T<:Real'包括所有向量('Vector'),其元素是实数('Real`)。
如果未指定边界变量,则默认为 '任何`:
Vector{T} where T # краткая форма для `where T<:Any`
变量也可以具有下限。:
Vector{T} where T>:Int
Vector{T} where Int<:T<:Real
嵌套的"where"表达式还有一个缩写语法。 例如,这段代码:
Pair{T, S} where S<:Array{T} where T<:Number
它可以缩短如下:
Pair{T, S} where {T<:Number, S<:Array{T}}
这种形式通常在方法签名中找到。
请注意,当使用这种形式的表示法时,变量从最外层开始列出。 这对应于使用语法'T将类型应用于参数值时替换变量的顺序{p1, p2, ...}`.
# <无翻译>’。..'*-Keyword</no-翻译>
...
的展开运算符(splat运算符,'。..`)表示参数序列。 的''运算符。..在函数定义中可以使用`来表示函数接受任意数量的参数。 使用''运算符。..'您也可以将函数应用于参数序列。
例子
julia> add(xs...) = reduce(+, xs)
add (generic function with 1 method)
julia> add(1, 2, 3, 4, 5)
15
julia> add([1, 2, 3]...)
6
julia> add(7, 1:100..., 1000:1100...)
111107
#
*;'
-Keyword
;
`;'字符在Julia中执行与许多类似C的语言相同的角色,表示前面语句的结束。
';'字符不必位于行尾:它可以用于在一行中分隔运算符或将运算符组合到单个表达式中。
如果在REPL中的一行末尾添加`;`,则不会输出此表达式的结果。
在函数声明中,`;'字符将常规参数与命名参数分开。 出于同样的目的,它可以在函数调用中使用。
在数组字面量中,用分号分隔的参数的内容被组合在一起。 如果分隔符是单个字符`;`,则内容垂直组合(即沿着第一维),在分隔符的情况下`;;`内容水平组合(在第二维),在分隔符的情况下';;;'统一发生在第三维等。 这样的分隔符也可以在方括号中的最后位置使用,以添加长度1的最终尺寸。
括号中第一个位置的字符';`可用于构造命名元组。 相同的语法'(;。..赋值左侧的`允许您析构属性。
如果在标准REPL环境中的空行中输入字符';`,它将切换到shell模式。
例子
julia> function foo()
x = "Hello, "; x *= "World!"
return x
end
foo (generic function with 1 method)
julia> bar() = (x = "Hello, Mars!"; return x)
bar (generic function with 1 method)
julia> foo();
julia> bar()
"Hello, Mars!"
julia> function plot(x, y; style="solid", width=1, color="black")
###
end
julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> [1; 3;; 2; 4;;; 10*A]
2×2×2 Array{Int64, 3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
10 20
30 40
julia> [2; 3;;;]
2×1×1 Array{Int64, 3}:
[:, :, 1] =
2
3
julia> nt = (; x=1) # без символа «;» или запятой в конце происходило бы присваивание переменной x
(x = 1,)
julia> key = :a; c = 3;
julia> nt2 = (; key => 1, b=2, c, nt.x)
(a = 1, b = 2, c = 3, x = 1)
julia> (; b, x) = nt2; # задаем переменные b и x путем деструктуризации свойств
julia> b, x
(2, 1)
julia> ; # при вводе «;» приглашение к вводу меняется на shell>
shell> echo hello
hello
# ’='*-Keyword
=
'='是赋值运算符。
-
如果`a`是一个变量,`b`是一个表达式,作为赋值`a=b`的结果,变量`a`将引用值`b'。
-
对于函数`f(x)
,赋值`f(x)=x’定义了一个新的常量函数’f
,或者,如果函数`f`已经定义,则向`f’添加一个新方法。 这个用例等同于语法’function f(x);x;end'。 -
a[i]=v’原因 'setindex!
'(a,v,i)'。 -
a.b=c’原因 'setproperty!
'(a,:b,c)'。 -
在函数调用’f(a=b)`中,传递`b`作为命名参数’a’的值。
-
在带逗号的括号内`(a=1,)'创建类型的实例 'NamedTuple'。
例子
将对象`b’分配给变量’a`时,不会创建`b’的副本;要做到这一点,请使用函数 '复制'或 'deepcopy`。
julia> b = [1]; a = b; b[1] = 2; a
1-element Array{Int64, 1}:
2
julia> b = [1]; a = copy(b); b[1] = 2; a
1-element Array{Int64, 1}:
1
传递给函数的集合也不会被复制。 函数可以更改其参数引用的对象的内容。 (习惯上加上后缀"!"这些功能的名称。)
julia> function f!(x); x[:] .+= 1; end
f! (generic function with 1 method)
julia> a = [1]; f!(a); a
1-element Array{Int64, 1}:
2
可迭代对象的值可以并行分配给多个变量。:
julia> a, b = 4, 5
(4, 5)
julia> a, b = 1:3
1:3
julia> a, b
(1, 2)
您可以按顺序为多个变量赋值。 这将返回最右边表达式的值。:
julia> a = [1]; b = [2]; c = [3]; a = b = c
1-element Array{Int64, 1}:
3
julia> b[1] = 2; a, b, c
([2], [2], [2])
julia> a = [1, 1]; a[3] = 2
ERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3]
[...]
julia> push!(a, 2, 3)
4-element Array{Int64, 1}:
1
1
2
3
分配`[]'时,不会删除集合中的项;相反,使用函数 '过滤器!`.
julia> a = collect(1:3); a[a .<= 1] = []
ERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations
[...]
julia> filter!(x -> x > 1, a) # операция производится на месте и поэтому эффективнее, чем a = a[a .> 1]
2-element Array{Int64, 1}:
2
3
# <无翻译>*`?:'*-Keyword</no-翻译>
a ? b : c
写条件运算符的简短形式;表示"如果’a`,计算’b`,否则计算`c'"。 也叫https://en.wikipedia.org/wiki/%3F:[三元运算符]。
此语法等效于’if a;b else c end',但通常用于强调更复杂表达式内的`b`和`c`之间的选择,而不是计算`b`或`c’的后果。
有关更多信息,请参阅手册的部分 执行顺序。
例子
julia> x = 1; y = 2;
julia> x > y ? println("x is larger") : println("x is not larger")
x is not larger
julia> x > y ? "x is larger" : x == y ? "x and y are equal" : "y is larger"
"y is larger"
标准模块
# ’Main'*-Module
Main
'Main’是一个顶级模块。 最初,在Julia中,`Main’模块是当前模块。 在命令行上定义的变量被添加到’Main’模块中,并且’varinfo’函数从`Main’模块返回变量。
julia> @__MODULE__
Main
# ’Core'*-Module
Core
"核心"模块包含被认为嵌入在语言中的所有标识符,这意味着它们是语言本身的一部分,而不是库。 "使用核心"命令隐式应用于每个模块,因为没有这些定义就不可能进行操作。
# ’Base'*-Module
Base
朱莉娅的基本图书馆。 'Base’模块包含主要功能(`base/'的内容)。 所有模块都隐式使用’using Base’命令,因为这些功能在绝大多数情况下都是必要的。
基本子模块
所有对象
# '核心。:==='-Function
===(x,y) -> Bool
≡(x,y) -> Bool
确定`x`和`y’是否相同,即对于任何程序都无法区分。 首先,比较类型`x`和’y'。 如果它们相同,则可变对象按内存中的地址进行比较,而不可变对象(如数字)按位级别的内容进行比较。 有时这个函数被称为egal。 它总是返回`Bool’类型的值。
例子
julia> a = [1, 2]; b = [1, 2];
朱莉娅>a==b
真的
朱莉娅>a===b
错误
朱莉娅>a===a
真的
# ’核心。isa'*-Function
isa(x, type) -> Bool
确定’x’是否属于类型’type'。 它也可以用作中缀运算符,例如`x isa type'。
例子
julia> isa(1, Int)
true
julia> isa(1, Matrix)
false
julia> isa(1, Char)
false
julia> isa(1, Number)
true
julia> 1 isa Number
true
# '基。isequal'-Function
isequal(x, y) -> Bool
同样地 ==,除了处理浮点数和缺失值。 'Isequal’函数将`NaN’的所有浮点值视为彼此相等,'-0.0’的值视为不等于'0.0',并且 'missing'--等于`missing'。 它总是返回`Bool’类型的值。
'isequal’是一个等价关系:它是自反(===`暗示`isequal
),对称(isequal(a,b)`暗示`isequal(b,a)
)和传递(isequal(a,b)`和`isequal(b,c)`暗示`isequal(a,c)
)。
实施
'Isequal’函数的默认实现调用'==,因此对于与浮点值不相关的类型,通常使用
=='就足够了。
'isequal’是哈希表(Dict
)使用的比较函数。 'hash(x)==hash(y)`应遵循’isequal(x,y)'。
这通常意味着有自定义方法`==`或`isequal`的类型必须实现相应的方法。 'hash'(反之亦然)。 集合的`isequal’的实现通常对所有内容递归调用’isequal'。
此外,'isequal’函数与 'isless',并且它们一起定义了一个固定的一般顺序:只有表达式`isequal(x,y),`isless(x,y)`或`isless(y,x)`中的一个必须是`true'(另外两个必须是`false
)。
标量类型通常不需要将`isequal`与`=='分开实现,除非它们表示浮点数,对于这些浮点数,可能比通用方法(基于`isnan`,signbit`和
==`)更有效的实现。
例子
julia> isequal([1., NaN], [1., NaN])
true
julia> [1., NaN] == [1., NaN]
false
julia> 0.0 == -0.0
true
julia> isequal(0.0, -0.0)
false
julia> missing == missing
missing
茱莉亚>isequal(漏,漏)
真的
isequal(x)
创建一个函数,其参数通过"x"进行比较 'isequal`,即相当于`y->isequal(y,x)'的函数。
返回的函数类型为"Base"。修正2{typeof(isequal)}`并可用于实施专门的方法。
# '基。isless`-Function
isless(x, y)
根据固定的一般顺序(结合函数确定)检查`x`是否小于`y` 'isequal')。 没有为所有类型对`(x,y)`定义’isless’函数。 但是,如果定义,则必须满足以下条件。
-
如果定义了’isless(x,y)
,那么也应该定义`isless(y,x)`和`isequal(x,y)
,并且这三个表达式中只有一个应该返回值`true'。 -
函数`isless`定义的关系是传递性的,即从’isless(x,y)&&isless(y,z)
跟随`isless(x,z)
。
通常无序的值(如"NaN")遵循正常值。 按值的顺序排列 '失踪`在最后。
这是函数使用的默认比较 '排序!`.
实施
应该为具有公共顺序的非数值类型实现此函数。 对于数值类型,只有在类型提供特殊值(例如`NaN')时才必须实现它。 具有部分顺序的类型必须实现 <
. 在文档中 替代排序您可以学习如何定义排序和类似功能中使用的替代排序方法。
例子
julia> isless(1, 3)
true
julia> isless("Red", "Blue")
false
# '基。ifelse'-Function
ifelse(condition::Bool, x, y)
如果`condition`为`true`,则返回`x',否则返回`y`。 它与`不同吗?`或’if’因为它是一个常规函数,所以首先评估所有参数。 在某些情况下,使用`ifelse`而不是`if`运算符可以消除生成代码中的分支,并确保连续循环的更高性能。
例子
julia> ifelse(1 > 2, 1, 2)
2
# ’核心。typeassert'*-Function
typeassert(x, type)
导致错误 'TypeError',如果不满足条件`x isa type'。 使用语法`x::type’时调用此函数。
例子
julia> typeassert(2.5, Int)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
Stacktrace:
[...]
# ’核心。元组'*-Function
tuple(xs...)
创建指定对象的元组。
另请参阅说明 '元组', ntuple'
和 'NamedTuple。
例子
julia> tuple(1, 'b', pi)
(1, 'b', π)
julia> ans === (1, 'b', π)
true
julia> Tuple(Real[1, 2, pi]) # принимает коллекцию
(1, 2, π)
# '基。ntuple'-Function
ntuple(f, n::Integer)
创建一个长度为`n`的元组,每个元素都使用函数`f(i)`计算,其中`i`是元素的索引。
例子
julia> ntuple(i -> 2*i, 4)
(2, 4, 6, 8)
ntuple(f, ::Val{N})
创建一个长度为`N`的元组,每个元素都使用函数`f(i)`计算,其中`i`是元素的索引。 由于使用’Val(N)`参数,使用ntuple函数的此变体创建的代码可以比将长度指定为整数时更有效。 但是在编译时无法确定`n`的情况下,选项`ntuple(f,N)`比`ntuple(f,Val(N))`更可取。
例子
julia> ntuple(i -> 2*i, Val(4))
(2, 4, 6, 8)
# '基。hash'-Function
hash(x[, h::UInt]) -> UInt
计算一个整数哈希码,使得’isequal(x,y)`暗示`hash(x)==hash(y)'。 可选的第二个参数’h’是与结果混合的哈希码。
对于新类型,应该实现具有两个参数的表单。 为此,通常递归调用具有两个参数的`hash`函数,以便将内容哈希相互混合(并与`h’混合)。 通常,为其实现哈希函数的任何类型也必须具有自己的实现。 ==(因此 'isequal'),从而满足上述条件。
启动新的Julia进程时,哈希值可能会发生变化。
julia> a = hash(10)
0x95ea2955abd45275
julia> hash(10, a) # использовать в качестве второго аргумента только выходные данные другой хэш-функции
0xd42bad54a8575b16
另请参阅说明 'objectid', 'Dict', '设置'。
# '基。终结器'-Function
finalizer(f, x)
注册函数`f(x)`,如果程序没有对`x`的引用,则应调用该函数,并返回`x'。 'x’必须是`mutable struct’类型,否则此函数将返回错误。
'F’函数不应该导致任务切换,这意味着消除了`println’等大多数I/O操作。 出于调试目的,使用宏`@async`(延迟上下文切换直到终结器执行完成)或关键字`ccall`直接调用C I/O函数可能很有用。
请注意,"世界年龄"不能保证可用于执行"f"功能。 它可以在注册终结者的"世界年龄"或任何以后的"世界年龄"被调用。
例子
finalizer(my_mutable_struct) do x
@async println("Finalizing $x.")
end
finalizer(my_mutable_struct) do x
ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.", repr(x))
end
可以在创建对象时注册终结器。 请注意,下面的示例隐式假定终结器返回创建的可变结构’x'。
mutable struct MyMutableStruct
bar
function MyMutableStruct(bar)
x = new(bar)
f(t) = @async println("Finalizing $t.")
finalizer(f, x)
end
end
# '基。复制'-Function
copy(x)
创建"x"的浅拷贝:复制外部结构,但不复制内部值。 例如,当复制一个数组时,创建一个数组的元素与原始数组相同。
另请参阅说明 '复制!, '复制!和 'deepcopy`。
# '基。deepcopy'—Function
deepcopy(x)
创建`x’的深度副本:递归复制整个内容,从而获得完全独立的对象。 例如,当深度复制数组时,创建其中包含的所有对象的深度副本,并获得具有一致关系结构的新数组(例如,如果原始数组中的前两个元素是同一个对象,则 对对象调用`deepcopy’函数通常等同于序列化它,然后反序列化它。
虽然这通常不是必需的,但在用户定义类型中,您可以复盖`deepcopy`函数的默认行为。 为此,定义了`deepcopy_internal(x::T,dict’函数的专用版本。::IdDict)(不用于其他目的)。 这里,'T’是重新定义函数的类型,`dict’跟踪递归复制的对象。 在定义中,应该使用`deepcopy_internal’而不是’deepcopy
,并且在返回之前应该相应地更新`dict’变量。
# '基。getproperty`-Function
getproperty(value, name::Symbol)
getproperty(value, name::Symbol, order::Symbol)
语法是`a.b`调用’getproperty(a,:b)'。 使用语法'@atomic order a.b`,调用`getproperty(a,:b,:order),并使用语法
@atomic a.b',调用`getproperty(a,:b,:sequentially_consistent)`。
例子
julia> struct MyType{T <: Number}
x::T
end
julia> function Base.getproperty(obj::MyType, sym::Symbol)
if sym === :special
return obj.x + 1
else # использовать getfield
return getfield(obj, sym)
end
end
julia> obj = MyType(1);
julia> obj.special
2
朱莉娅>反对。x
1
只有在必要时才重载"getproperty",因为如果语法行为是"obj",这可能会导致混淆。f’是不寻常的。 另外,请记住,使用方法通常是可取的。 有关更多信息,请参阅样式指南。: 使用导出的方法而不是直接访问字段。
另请参阅说明 '盖菲尔德', 'propertynames'和 'setproperty!`.
# '基。setproperty!`-Function</no-翻译>
setproperty!(value, name::Symbol, x)
setproperty!(value, name::Symbol, x, order::Symbol)
语法’a.b=c’调用’setproperty!(a,:b,c)'。 使用语法"@atomic order a.b=c",调用"setproperty!(a,:b,c,:order),并使用语法
@atomic a.b=c',调用`setproperty!(a,:b,c,:sequentially_consistent)'。
兼容性:Julia1.8
为’setproperty!'在模块中,需要至少1.8的Julia版本。 |
另请参阅说明 '塞特菲尔德!`, 'propertynames'和 'getproperty'。
# '基。更换产品!`-Function</no-翻译>
replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
"X.f"的执行是根据规则将"期望"与"期望"交换的比较操作。 语法'@atomicreplace x.f expected=>desired`可以用来代替函数调用形式。
另请参阅说明 '替换!'setproperty!和 'setpropertyonce!`.
# '基。swapproperty!`-Function</no-翻译>
swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)
语法'@atomic a.b,_=c,a.b`返回`(c,swapproperty!(a,:b,c,:sequentially_consistent))`,其中两个部分都应该有一个通用表达式`getproperty'。
另请参阅说明 '斯瓦普菲尔德!和 'setproperty!.
# '基。modifyproperty!`-Function</no-翻译>
modifyproperty!(x, f::Symbol, op, v, order::Symbol=:not_atomic)
语法'@atomic op(x.f,v)(及其等价的
@atomic x.f op v`)返回`modifyproperty!(x,:f,op,v,:sequentially_consistent)`,其中第一个参数必须是’getproperty`表达式,并且以原子方式更改。
调用’op(getproperty(x,f),v)`应该返回可以存储在’x`对象的`f`字段中的默认值。 特别是,与行为相反 'setproperty!'默认情况下,`convert`函数不会自动调用。
另请参阅说明 '莫迪菲尔德!和 'setproperty!.
# '基。setpropertyonce!`-Function</no-翻译>
setpropertyonce!(x, f::Symbol, value, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)
对`x.f`执行与交换的比较操作,如果之前没有设置,则分配值`value'。 可以使用语法`@atomiconce x.f=value’来代替函数调用形式。
另请参阅说明 'setfieldonce!, 'setproperty!和 'replaceproperty!`.
兼容性:Julia1.11
此功能需要Julia至少1.11的版本。 |
# '基。propertynames'-Function
propertynames(x, private=false)
返回对象`x`的属性(x.property
)的元组或向量。 它的作用方式通常与 'fieldnames(typeof(x)’,但重载函数的类型 `getproperty'通常还必须重载’propertynames’以获取类型实例的属性。
函数’propertynames(x)`只能返回对象’x’的文档接口中包含的公共属性的名称。 如果您还需要返回供内部使用的私有属性的名称,请为可选的第二个参数传递值"true"。 当在REPL中使用TAB键自动完成’x.'时,只显示`private=false’的属性。
另请参阅说明 'hasproperty`, '哈斯菲尔德'。
# ’核心。getfield'*-Function
getfield(value, name::Symbol, [order::Symbol])
getfield(value, i::Int, [order::Symbol])
按名称或位置从复合"值"对象中提取字段。 如有必要,您可以指定此操作的顺序。 如果字段使用关键字`@atomic’声明,强烈建议指定的顺序与此位置的保存操作兼容。 否则,如果缺少'@atomic’声明并且指定了此参数,则应为`:not_atomic'。 另请参阅说明 `getproperty'和 '字段名'。
例子
julia> a = 1//2
1//2
julia> getfield(a, :num)
1
julia> a.num
1
julia> getfield(a, 1)
1
#
'核心。塞特菲尔德!
*-Function</no-翻译>
setfield!(value, name::Symbol, x, [order::Symbol])
setfield!(value, i::Int, x, [order::Symbol])
将`x`赋给复合类型的`value`对象的命名字段。 'Value’对象必须是可变的,并且’x’必须是`fieldtype(typeof(value),name)的子类型。 此外,您可以指定此操作的顺序。 如果字段使用关键字
@atomic’声明,则必须指定顺序。 否则,如果缺少'@atomic’声明并且指定了此参数,则应为`:not_atomic'。 另请参阅说明 'setproperty!`.
例子
julia> mutable struct MyMutableStruct
field::Int
end
julia> a = MyMutableStruct(1);
julia> setfield!(a, :field, 2);
julia> getfield(a, :field)
2
julia> a = 1//2
1//2
julia> setfield!(a, :num, 3);
ERROR: setfield!: immutable struct of type Rational cannot be changed
#
'核心。莫迪菲尔德!
*-Function</no-翻译>
modifyfield!(value, name::Symbol, op, x, [order::Symbol]) -> Pair
modifyfield!(value, i::Int, op, x, [order::Symbol]) -> Pair
在应用`op`函数后,原子地执行获取和设置字段的操作。
y = getfield(value, name) z = op(y, x) setfield!(value, name, z) return y => z
如果这样的特征(例如,原子增量)由硬件支持,则可以使用适当的硬件指令来优化操作。 否则,将使用循环。
兼容性:Julia1.7
此功能需要Julia至少1.7的版本。 |
# '核心。替换场!`-Function</no-翻译>
replacefield!(value, name::Symbol, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
replacefield!(value, i::Int, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
原子地执行获取字段并有条件地为其分配指定值的操作。
y = getfield(value, name, fail_order) ok = y === expected if ok setfield!(value, name, desired, success_order) end return (; old = y, success = ok)
如果硬件支持此功能,则可以使用适当的硬件指令优化操作。 否则,将使用循环。
兼容性:Julia1.7
此功能需要Julia至少1.7的版本。 |
#
'核心。斯瓦普菲尔德!
*-Function</no-翻译>
swapfield!(value, name::Symbol, x, [order::Symbol])
swapfield!(value, i::Int, x, [order::Symbol])
原子地执行同时进行现场采集和分配的操作:
y = getfield(value, name) setfield!(value, name, x) return y
兼容性:Julia1.7
此功能需要Julia至少1.7的版本。 |
#
'核心。setfieldonce!
*-Function</no-翻译>
setfieldonce!(value, name::Union{Int,Symbol}, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
如果尚未设置指定值,则原子地执行将指定值分配给字段的操作。
ok = !isdefined(value, name, fail_order) if ok setfield!(value, name, desired, success_order) end return ok
兼容性:Julia1.11
此功能需要Julia至少1.11的版本。 |
#
'核心。被定义
*-Function
isdefined(m::Module, s::Symbol, [order::Symbol])
isdefined(object, s::Symbol, [order::Symbol])
isdefined(object, index::Int, [order::Symbol])
检查是否定义了全局变量或对象字段。 参数可以是模块和符号、复合对象和字段名(以符号的形式)或索引。 如有必要,您可以指定此操作的顺序。 如果字段使用关键字`@atomic’声明,强烈建议指定的顺序与此位置的保存操作兼容。 否则,如果缺少'@atomic’声明并且指定了此参数,则应为`:not_atomic'。
要检查是否定义了数组元素,请改用该函数 'isassigned'。
另请参阅说明 '@被定义`。
例子
julia> isdefined(Base, :sum)
true
julia> isdefined(Base, :NonExistentMethod)
false
julia> a = 1//2;
julia> isdefined(a, 2)
true
julia> isdefined(a, 3)
false
julia> isdefined(a, :num)
true
julia> isdefined(a, :numerator)
false
# '基。@isdefined'-Macro
@isdefined s -> Bool
检查变量’s’是否在当前作用域中定义。
另请参阅功能说明 `isdefined',它检查字段,函数的属性 `isassigned',检查数组索引和函数 `haskey',它检查其他映射。
例子
julia> @isdefined newvar
false
julia> newvar = 1
1
julia> @isdefined newvar
true
julia> function f()
println(@isdefined x)
x = 3
println(@isdefined x)
end
f (generic function with 1 method)
朱莉娅>f()
错误
真的
# '基。转换'-Function
convert(T, x)
将`x’转换为`T’类型的值。
如果’T’是整数类型('Integer'),发生错误 'InexactError'在值`x`不能表示为类型`T`的情况下,例如,如果值`x`不是整数或超出类型`T`支持的范围。
例子
julia> convert(Int, 3.0)
3
julia> convert(Int, 3.5)
ERROR: InexactError: Int64(3.5)
Stacktrace:
[...]
如果’T’是一个类型 `AbstractFloat',返回最接近`x`的值,由类型`T’支持。 当确定最近的值时,Inf被认为是一个大于`floatmax(T)'的最小精度单位(ulp)的值。
julia> x = 1/3
0.3333333333333333
julia> convert(Float32, x)
0.33333334f0
julia> convert(BigFloat, x)
0.333333333333333314829616256247390992939472198486328125
如果’T’是集合类型并且’x’是集合,则`convert(T,x)`函数可以返回整个对象`x’或其中一部分的别名。
julia> x = Int[1, 2, 3];
julia> y = convert(Vector{Int}, x);
julia> y === x
true
# '基。促进'-Function
promote(xs...)
将所有参数转换为通用类型并将其作为元组返回。 如果不能转换任何参数,则会发生错误。
另请参阅说明 '促进型', 'promote_rule'。
例子
julia> promote(Int8(1), Float16(4.5), Float32(4.1))
(1.0f0, 4.5f0, 4.1f0)
julia> promote_type(Int8, Float16, Float32)
Float32
julia> reduce(Base.promote_typejoin, (Int8, Float16, Float32))
Real
julia> promote(1, "x")
ERROR: promotion of types Int64 and String failed to change any arguments
[...]
julia> promote_type(Int, String)
Any
# '基。oftype'-Function
oftype(x, y)
将`y’转换为对象类型’x`,即`convert(typeof(x),y)'。
例子
julia> x = 4;
julia> y = 3.;
julia> oftype(x, y)
3
julia> oftype(y, x)
4.0
# '基。加宽`-Function
widen(x)
如果’x’是一个类型,它返回一个更广泛的类型,即保证算术运算`+和
-`在不溢出和损失精度的情况下执行,类型`x`支持的任何值组合。
对于长度小于128位的固定大小整数类型,`widen`函数返回位数两倍的类型。
如果’x’是一个值,则转换为’widen(typeof(x)’。
例子
julia> widen(Int32)
Int64
julia> widen(1.5f0)
1.5
# '基。身份`-Function
identity(x)
的身份函数。 返回其参数。
另请参阅功能说明 'one`和 oneunit
和库中的`I’运算符 'LinearAlgebra'。
例子
julia> identity("Well, what did you expect?")
"Well, what did you expect?"
# '核心。WeakRef'-Type
WeakRef(x)
w=WeakRef(x)'创建https://en.wikipedia.org/wiki/Weak_reference [弱引用]对Julia的值’x`的引用:虽然`w`包含对`x`的引用,但这并不妨碍垃圾收集器删除`x’的值。 `w.value’具有值’x
(如果`x`尚未被垃圾回收器删除)或`nothing`(如果`x’已被垃圾回收器删除)。
julia> x = "a string"
"a string"
julia> w = WeakRef(x)
WeakRef("a string")
julia> GC.gc()
julia> w # ссылка поддерживается посредством `x`
WeakRef("a string")
julia> x = nothing # очищаем ссылку
julia> GC.gc()
julia> w
WeakRef(nothing)
类型属性
类型关系
# '核心。类型'-Type
Core.Type{T}
'核心。Type’是一种抽象类型,其中所有类型的对象都是实例。 单类型'Core的唯一实例。类型{T}'--对象’T'。
例子
julia> isa(Type{Float64}, Type)
true
julia> isa(Float64, Type)
true
julia> isa(Real, Type{Float64})
false
julia> isa(Real, Type{Real})
true
# ’核心。数据类型'*-Type
DataType <: Type{T}
'DataType’表示具有名称,显式声明超类型和(可选)参数的显式声明类型。 系统中的每个特定值都是某种类型的"数据类型"的实例。
例子
julia> typeof(Real)
DataType
julia> typeof(Int)
DataType
julia> struct Point
x::Int
y
end
julia> typeof(Point)
DataType
#
'核心。:<:
*-Function</no-翻译>
<:(T1, T2)
子类型运算符:当且仅当`T1`类型的所有值也是`T2`类型时,才返回`true'。
例子
julia> Float64 <: AbstractFloat
true
julia> Vector{Int} <: AbstractArray
true
julia> Matrix{Float64} <: Matrix{AbstractFloat}
false
# '基。typejoin'-Function
typejoin(T, S, ...)
返回类型`T`和`S’的最接近的共同祖先,即它们都继承的最窄类型。 对具有变量编号的其他参数执行递归。
例子
julia> typejoin(Int, Float64)
Real
julia> typejoin(Int, Float64, ComplexF32)
Number
# '基。typeintersect'-Function
typeintersect(T::Type, S::Type)
计算包含类型`T`和`S`交集的类型。 这通常是最窄的类型或最接近它。
保证确切行为的特殊情况:对于`T<:S`,'typeintersect(S,T)==T==typeintersect(T,S)`。
# '基。promote_type'-Function
promote_type(type1, type2, ...)
提升是指将混合类型的值转换为一种通用类型。 'promote_type’表示Julia中默认的提升方式,当运算符(通常是数学运算符)接收不同类型的参数时。 通常,'promote_type’函数尝试返回一个类型,该类型允许至少近似地表达每个输入类型的大部分值,而无需不必要的扩展。 有些损失是可以接受的。 例如,'promote_type(Int64,Float64)'返回 'Float64',虽然,严格来说,不是所有的值 'Int64'可以完全表示为’Float64’的值。
另请参阅说明 '促进', '促进_typejoin`, 'promote_rule'。
例子
julia> promote_type(Int64, Float64)
Float64
julia> promote_type(Int32, Int64)
Int64
julia> promote_type(Float32, BigInt)
BigFloat
julia> promote_type(Int16, Float16)
Float16
julia> promote_type(Int64, Float16)
Float16
julia> promote_type(Int8, UInt16)
UInt16
!!! 警告"不要直接超载" 要为自己的类型重载提升,请重载函数 'promote_rule'。 函数`promote_rule`在’promote_type’内部调用以确定类型。 如果直接重载’promote_type',则可能由于歧义而发生错误。
# '基。promote_typejoin'-Function
promote_typejoin(T, S)
计算同时包含类型`T`和类型`S’的类型。 结果类型可以是两种输入类型的父类型,也可以是它们的联合。 它用作备份选项 'typejoin'。
另请参阅功能说明 '促进'和 'promote_type'。
例子
julia> Base.promote_typejoin(Int, Float64)
Real
julia> Base.promote_type(Int, Float64)
Float64
# '基。isdispatchtuple'-Function
isdispatchtuple(T)
确定类型’T’是否是元组的"最终类型",即它可以在分派期间用作类型签名,并且没有可以在调用中使用的子类型(或超类型)。 如果’T’不是类型,则返回’false'。
申报结构
# '基。ismutable`-Function
ismutable(v) -> Bool
当且仅当`v`的值是可变的时,才返回`true`。 在该部分 可变复合类型详细讨论了可变性的概念。 请注意,此函数适用于值,因此如果您将`DataType`类型传递给它,它将确定值类型是可变的。
出于技术原因’ismutable`对于某些特殊类型的值(例如, |
另请参阅说明 'isbits'和 'isstructtype'。
例子
julia> ismutable(1)
false
julia> ismutable([1,2])
true
兼容性:Julia1.5
此功能需要1.5或更高的Julia版本。 |
# '基。ismutabletype'-Function
ismutabletype(T) -> Bool
确定类型’T’是否已被声明为可变(即使用关键字`mutable struct')。 如果’T’不是类型,则返回’false'。
兼容性:Julia1.7
此功能需要Julia至少1.7的版本。 |
# '基。isabstracttype'-Function
isabstracttype(T)
确定类型’T`是否被声明为abstract(即使用语法’abstract type')。 请注意,这不是`isconcretetype(T)'的否定。 如果’T’不是类型,则返回’false'。
例子
julia> isabstracttype(AbstractArray)
true
julia> isabstracttype(Vector)
false
# '基。isprimitivetype'-Function
isprimitivetype(T) -> Bool
确定类型"T"是否被声明为原始类型(即使用语法"原始类型")。 如果’T’不是类型,则返回’false'。
# '基。issingletontype'-Function
Base.issingletontype(T)
确定类型`T`是否只能有一个实例,例如,在无字段结构类型的情况下,除了其他单个值。 如果’T’不是特定类型,则返回’false'。
# '基。isstructtype'-Function
isstructtype(T) -> Bool
确定类型’T’是否被声明为结构类型(即使用关键字’struct’或’mutable struct')。 如果’T’不是类型,则返回’false'。
# '基。名称'-Method</no-翻译>
nameof(t::DataType) -> Symbol
返回`DataType`类型的名称(可能封装在`unionAll’中,没有父模块的名称)作为字符。
例子
julia> module Foo
struct S{T}
end
end
Foo
julia> nameof(Foo.S{T} where T)
:S
# '基。字段名'-Function</no-翻译>
fieldnames(x::DataType)
返回一个元组,其中包含`DataType’类型字段的名称。
另请参阅说明 'propertynames'和 '哈斯菲尔德'。
例子
julia> fieldnames(Rational)
(:num, :den)
julia> fieldnames(typeof(1+im))
(:re, :im)
# '基。字段名'-Function
fieldname(x::DataType, i::Integer)
返回具有索引`I`的字段名称,类型为`DataType'。
例子
julia> fieldname(Rational, 1)
:num
julia> fieldname(Rational, 2)
:den
# ’核心。fieldtype'*-Function
fieldtype(T, name::Symbol | index::Int)
定义复合数据类型’T’中字段的声明类型(通过名称或索引指定)。
例子
julia> struct Foo
x::Int64
y::String
end
julia> fieldtype(Foo, :x)
Int64
julia> fieldtype(Foo, 2)
String
# '基。fieldtypes'-Function
fieldtypes(T::Type)
以元组的形式返回复合数据类型`T`的所有字段的声明类型。
兼容性:Julia1.1
此功能需要至少1.1的Julia版本。 |
例子
julia> struct Foo
x::Int64
y::String
end
julia> fieldtypes(Foo)
(Int64, String)
# '基。hasfield'—Function
hasfield(T::Type, name::Symbol)
返回一个布尔值,指示类型`T`是否有自己的’name`字段。
另请参阅说明 '字段名', 'fieldcount'和 'hasproperty`。
兼容性:Julia1.2
此功能需要至少1.2的Julia版本。 |
例子
julia> struct Foo
bar::Int
end
julia> hasfield(Foo, :bar)
true
julia> hasfield(Foo, :x)
false
# ’核心。nfields'*-Function
nfields(x) -> Int
返回指定对象的字段数。
例子
julia> a = 1//2;
julia> nfields(a)
2
julia> b = 1
1
julia> nfields(b)
0
julia> ex = ErrorException("I've done a bad thing");
julia> nfields(ex)
1
在这些例子中,`a’是类型 'Rational',它有两个字段。 字段’b`是类型’Int'-没有字段的原始位类型。 "Ex"字段具有类型 `ErrorException'与一个字段。
# '基。isconst'-Function
isconst(m::Module, s::Symbol) -> Bool
确定全局变量是否在`m’模块中声明为’const'。
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool
确定字段’s`是否在类型’t`中声明为`const'。
# '基。isfieldatomic'-Function
isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool
确定’s’字段是否在`t`类型中声明为`@atomic'。
内存中的位置
# '基。sizeof'-Method
sizeof(T::DataType)
sizeof(obj)
指定类型`DataType``T`的规范二进制表示形式的字节大小,如果有的话。 或者`obj`对象的字节大小,如果它不是`DataType’类型的话。
另请参阅说明 '基地。summarysize'。
例子
julia> sizeof(Float32)
4
julia> sizeof(ComplexF64)
16
julia> sizeof(1.0)
8
julia> sizeof(collect(1.0:10.0))
80
julia> struct StructWithPadding
x::Int64
flag::Bool
end
julia> sizeof(StructWithPadding) # не сумма `sizeof` полей из-за заполнения
16
julia> sizeof(Int64) + sizeof(Bool) # отличается от приведенного выше
9
如果’DataType’T’类型没有特定的大小,则会发生错误。
julia> sizeof(AbstractArray)
ERROR: Abstract type AbstractArray does not have a definite size.
Stacktrace:
[...]
# '基。isconcretetype'-Function
isconcretetype(T)
确定类型`T`是否是特定的,也就是说,它可以有直接的实例(`x`的值使得`typeof(x)===T')。 请注意,这不是`isabstracttype(T)'的否定。 如果’T’不是类型,则返回’false'。
另请参阅说明 '轨道', 'isabstracttype', 'issingletontype'。
例子
julia> isconcretetype(Complex)
false
julia> isconcretetype(Complex{Float32})
true
julia> isconcretetype(Vector{Complex})
true
julia> isconcretetype(Vector{Complex{Float32}})
true
julia> isconcretetype(Union{})
false
julia> isconcretetype(Union{Int,String})
false
# '基。isbitstype'-Function
isbitstype(T)
如果`T`是一个简单的数据类型,即不可变的,并且不包含对除`primitive`和`isbitstype`类型的值以外的值的引用,则返回`true'。 一个典型的例子是数字类型,如 'UInt8`, Float64'
和 '+复杂{Float64}+. 此类别类型特别重要,因为它们可以用作类型参数,并且可能无法跟踪状态。 '被定义`或 'isassigned'并具有与C语言兼容的特定结构。 如果’T’不是类型,则返回’false'。
另请参阅说明 '轨道', 'isprimitivetype'和 'ismutable`。
例子
julia> isbitstype(Complex{Float64})
true
julia> isbitstype(Complex)
false
# '基。fieldoffset'-Function
fieldoffset(type, i)
返回类型为`i`索引的字段相对于数据开头的字节偏移量。 例如,使用该函数,可以如下获得有关结构的摘要信息。
julia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];
julia> structinfo(Base.Filesystem.StatStruct)
13-element Vector{Tuple{UInt64, Symbol, Type}}:
(0x0000000000000000, :desc, Union{RawFD, String})
(0x0000000000000008, :device, UInt64)
(0x0000000000000010, :inode, UInt64)
(0x0000000000000018, :mode, UInt64)
(0x0000000000000020, :nlink, Int64)
(0x0000000000000028, :uid, UInt64)
(0x0000000000000030, :gid, UInt64)
(0x0000000000000038, :rdev, UInt64)
(0x0000000000000040, :size, Int64)
(0x0000000000000048, :blksize, Int64)
(0x0000000000000050, :blocks, Int64)
(0x0000000000000058, :mtime, Float64)
(0x0000000000000060, :ctime, Float64)
# '基。datatype_alignment'-Function
Base.datatype_alignment(dt::DataType) -> Int
此类型实例的分配内存区域的最小对齐方式。 您可以为任何类型调用`isconcretetype`,但对于内存中的对象,返回元素的对齐方式,而不是整个对象。
# '基。datatype_haspadding'-Function
Base.datatype_haspadding(dt::DataType) -> Bool
确定此类型实例的字段是否放置在内存中而没有中间填充位(定义为当应用于结构的字段时,其值对相等性检查没有唯一影响的位)。 它可以为任何类型的"isconcretetype"调用。
# '基。datatype_pointerfree'-Function
Base.datatype_pointerfree(dt::DataType) -> Bool
确定此类型的实例是否可以包含对垃圾回收器控制的内存的引用。 它可以为任何类型的"isconcretetype"调用。
特殊值
# '基。typemin'-Function
typemin(T)
可以由指定的(实数)数字数据类型’T’表示的最小值。
例子
julia> typemin(Int8)
-128
julia> typemin(UInt32)
0x00000000
julia> typemin(Float16)
-Inf16
julia> typemin(Float32)
-Inf32
julia> nextfloat(-Inf32) # минимальное конечное число с плавающей запятой типа Float32
-3.4028235f38
# '基。typemax'-Function
typemax(T)
可以由指定的(真实)数字类型’DataType’表示的最大值。
另请参阅说明 'floatmax', '打字', 'eps'。
例子
julia> typemax(Int8)
127
julia> typemax(UInt32)
0xffffffff
julia> typemax(Float64)
Inf
julia> typemax(Float32)
Inf32
julia> floatmax(Float32) # максимальное конечное число с плавающей запятой типа Float32
3.4028235f38
# '基。floatmin'-Function
floatmin(T = Float64)
返回浮点类型’T’可以表示的最小正数。
例子
julia> floatmin(Float16)
Float16(6.104e-5)
julia> floatmin(Float32)
1.1754944f-38
julia> floatmin()
2.2250738585072014e-308
# '基。maxintfloat'-Function
maxintfloat(T=Float64)
可以由指定的浮点类型`T`(默认为`Float64`)精确表示的最大连续浮点整数。
换句话说,'maxintfloat’函数返回最小正浮点整数’n`,使得`n+1`不能由类型`T’精确表示。
如果需要整数类型值('Integer`),请使用`Integer(maxintfloat(T))`。
maxintfloat(T, S)
可以由指定的浮点类型`T`表示的最大连续整数,并且不超过可以由整数类型`S`表示的最大整数。 或者,等价地,这是`maxintfloat(T)的值的最小值和 'typemax(S)
。
# '基。eps'-Method
eps(::Type{T}) where T<:AbstractFloat
eps()
返回浮点类型’T’的机器epsilon(默认情况下,'T=Float64'`。 它被定义为1和下一个最大值之间的间隔,可以用类型`typeof(one(T))表示。 相当于’eps(one(T))
。 (由于`eps(T)'的值是`T’类型的相对误差范围,因此它是一个无量纲量,就像 '一`。)
例子
julia> eps()
2.220446049250313e-16
julia> eps(Float32)
1.1920929f-7
julia> 1.0 + eps()
1.0000000000000002
julia> 1.0 + eps()/2
1.0
# '基。eps'-Method
eps(x::AbstractFloat)
返回值`x`的最小精度单位(ulp)。 这是值为`x’的连续可表示浮点值之间的距离。 在大多数情况下,如果`x’两侧的距离不同,则取其中的较大者,即
eps(x) == max(x-prevfloat(x), nextfloat(x)-x)
此规则的例外情况是最小和最大结束值(例如,类型的`nextfloat(-Inf)`和`prevfloat(Inf) `Float64'),对其进行舍入到最小的距离。
Eps函数限制浮点数的舍入误差这一事实证明了这一点。 在默认舍入模式下,'RoundNearest’如果 --一个实数,和 --最接近的浮点数 然后
另请参阅说明 '下一层', '非正常', 'floatmax'。
例子
julia> eps(1.0)
2.220446049250313e-16
julia> eps(prevfloat(2.0))
2.220446049250313e-16
julia> eps(2.0)
4.440892098500626e-16
julia> x = prevfloat(Inf) # максимальное конечное значение Float64
1.7976931348623157e308
julia> x + eps(x)/2 # округление в большую сторону
Inf
julia> x + prevfloat(eps(x)/2) # округление в меньшую сторону
1.7976931348623157e308
# '基。实例'-Function
instances(T::Type)
返回指定类型的所有实例的集合(如果适用)。 它主要用于枚举类型(请参阅'@enum'`。
例子
julia> @enum Color red blue green
julia> instances(Color)
(red, blue, green)
特殊类型
# '核心。任何`-Type
Any::DataType
"任何"是所有类型的联合。 对于任何`x`,它具有特征属性`isa(x,Any)==true'。 因此,'Any’描述了可能值的总和。 例如,'Integer’是`Any’类型的子集,包括`Int`,`Int8`和其他整数类型。
#
'核心。Union'
-Type
Union{Types...}
类型的联合是一种抽象类型,它包括所有参数类型的所有实例。 这意味着’T<:Union{T,S}'和’S<:联合{T,S}`.
与其他抽象类型一样,不可能创建它的实例,即使它的所有参数都不是抽象的。
例子
julia> IntOrString = Union{Int,AbstractString}
Union{Int64, AbstractString}
julia> 1 isa IntOrString # экземпляр Int включен в объединение
true
julia> "Hello!" isa IntOrString # String также включен
true
julia> 1.0 isa IntOrString # Float64 не включен, так как не является ни Int, ни AbstractString
false
高级帮助
与大多数其他参数类型不同,联合在其参数中是协变的。 例如,'Union{Real, String}'是’Union的子类型{Number, AbstractString}`.
空关联 `Union{}'是Julia中最低的类型。
#
'核心。UnionAll
*-Type
UnionAll
通过类型参数的所有值组合类型。 'unionAll’用于描述某些参数值未知的参数类型。 有关更多信息,请参阅手册的部分 unionAll的类型。
例子
julia> typeof(Vector)
UnionAll
julia> typeof(Vector{Int})
DataType
# ’核心。元组'*-Type</no-翻译>
Tuple{Types...}
元组是一个固定长度的容器,可以包含各种类型的任何值,但不能更改(它是不可变的)。 这些值可以由索引访问。 元组字面量在括号中以逗号分隔。:
julia> (1, 1+1)
(1, 2)
julia> (1,)
(1,)
julia> x = (0.0, "hello", 6*7)
(0.0, "hello", 42)
julia> x[2]
"hello"
julia> typeof(x)
Tuple{Float64, String, Int64}
单位长度的元组必须用逗号写成,(1,’,
(1)`将只是括号中的值。 `()`表示一个空元组(长度为0)。
可以基于迭代器使用`Tuple`类型作为构造函数创建元组。:
julia> Tuple(["a", 1])
("a", 1)
julia> Tuple{String, Float64}(["a", 1])
("a", 1.0)
元组类型在其参数中是协变的’元组{Int}'是'元组的子类型{Any}`. 因此,'元组{Any}'被认为是抽象类型,元组类型只有在它们的参数是这样的情况下才是具体的。 元组没有字段名称;字段只能由索引访问。 元组类型可以有任意数量的参数。
请参阅手册中专门用于 元组类型。
另请参阅说明 '瓦拉格', 'NTuple`, 'ntuple`, '元组', 'NamedTuple`。
# ’核心。NamedTuple'*—Type
NamedTuple
'NamedTuple',顾名思义,是一个命名元组('元组')。 也就是说,它是一个类似元组的值集合,其中的每个元素都有一个唯一的名称,由 '符号'。 与`Tuple`类型一样,'NamedTuple’类型是不可变的:名称和值都不能在创建后直接更改。
命名元组可以创建为带有键的字面元组,例如`(a=1,b=2),作为在左括号后面带有分号的字面元组,例如
(;a=1,b=2)'(这种形式也接受编程生成的名称,如下所述),{(:a, :b)}1,2`.
您可以使用用于访问字段的语法(例如`x.a`)或使用函数来访问与命名元组中的名称关联的值 'getindex',例如,x[:a]`或`x[(:a,:b)]
。 名称的元组可以使用函数获得 'keys',以及使用函数的值元组 '价值观'。
当迭代’NamedTuple`时,返回不带名称的_values。 (请参阅下面的示例。)要遍历名称-值对,请使用函数 '对'。 |
使用宏声明’NamedTuple’类型很方便。 '@NamedTuple'。
例子
julia> x = (a=1, b=2)
(a = 1, b = 2)
julia> x.a
1
julia> x[:a]
1
julia> x[(:a,)]
(a = 1,)
julia> keys(x)
(:a, :b)
julia> values(x)
(1, 2)
julia> collect(x)
2-element Vector{Int64}:
1
2
julia> collect(pairs(x))
2-element Vector{Pair{Symbol, Int64}}:
:a => 1
:b => 2
就像在以编程方式定义命名参数的情况下一样,可以通过在元组字面量内的分号后面指定对`name::Symbol=>value`来创建命名元组。 此选项和语法"name=value"可以组合使用。:
julia> (; :a => 1, :b => 2, c=3)
(a = 1, b = 2, c = 3)
名称-值对也可以通过解包命名元组或任何生成两个值的集合的迭代器来提供,其中第一个值是一个字符。:
julia> keys = (:a, :b, :c); values = (1, 2, 3);
julia> NamedTuple{keys}(values)
(a = 1, b = 2, c = 3)
julia> (; (keys .=> values)...)
(a = 1, b = 2, c = 3)
julia> nt1 = (a=1, b=2);
julia> nt2 = (c=3, d=4);
julia> (; nt1..., nt2..., b=20) # последнее b перезаписывает значение из nt1
(a = 1, b = 20, c = 3, d = 4)
julia>(;zip(keys,values)...)#zip输出像(:a,1)这样的元组
(a=1,b=2,c=3)
与命名参数一样,标识符和点表达式假定使用名称。:
julia> x = 0
0
julia> t = (; x)
(x = 0,)
julia> (; t.x)
(x = 0,)
兼容性:Julia1.5
从Julia1.5开始,隐式名称可用于标识符和点表达式。 |
兼容性:Julia1.7
从Julia1.7开始,'getindex’方法可以与多个符号( |
# '基。@NamedTuple'-Macro
@NamedTuple{key1::Type1, key2::Type2, ...}
@NamedTuple begin key1::Type1; key2::Type2; ...; end
此宏为声明’NamedTuple’类型提供了更方便的语法。 它返回具有指定键和类型的类型`NamedTuple`,相当于表达式'NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}. 如果省略
::Type’声明,则假定为’Any’类型。 '开始。.. end'form允许您将声明分成几行(就像`struct`声明的情况一样)。 否则,这种形式没有什么不同。 输出’NamedTuple`类型时使用`NamedTuple’宏,例如在REPL中。
例如,元组`(a=3.1,b="hello")'具有类型’NamedTuple{(:a, :b), Tuple{Float64, String}}`. 使用宏'@NamedTuple`,可以这样声明:
julia> @NamedTuple{a::Float64, b::String}
@NamedTuple{a::Float64, b::String}
julia> @NamedTuple begin
a::Float64
b::String
end
@NamedTuple{a::Float64, b::String}
兼容性:Julia1.5
这个宏首先在Julia1.5中实现。 |
# '基。@Kwargs'-Macro
@Kwargs{key1::Type1, key2::Type2, ...}
此宏提供了一种使用与以下语法相同的语法构造命名参数类型的表示的方便方法 '@NamedTuple'。 例如,如果您有一个函数调用’func([位置参数];kw1=1.0,kw2="2"),则可以使用此宏以
@Kwargs形式创建命名参数类型的内部表示形式{kw1::Float64, kw2::String}`. 宏语法专门设计用于简化具有命名参数的方法在堆栈跟踪表示形式中输出时的签名类型。
julia> @Kwargs{init::Int} # внутреннее представление именованных аргументов
Base.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}
julia> sum("julia"; init=1)
ERROR: MethodError: no method matching +(::Char, ::Char)
The function `+` exists, but no method is defined for this combination of argument types.
Closest candidates are:
+(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:585
+(::Integer, ::AbstractChar)
@ Base char.jl:247
+(::T, ::Integer) where T<:AbstractChar
@ Base char.jl:237
Stacktrace:
[1] add_sum(x::Char, y::Char)
@ Base ./reduce.jl:24
[2] BottomRF
@ Base ./reduce.jl:86 [inlined]
[3] _foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, init::Int64, itr::String)
@ Base ./reduce.jl:62
[4] foldl_impl(op::Base.BottomRF{typeof(Base.add_sum)}, nt::Int64, itr::String)
@ Base ./reduce.jl:48 [inlined]
[5] mapfoldl_impl(f::typeof(identity), op::typeof(Base.add_sum), nt::Int64, itr::String)
@ Base ./reduce.jl:44 [inlined]
[6] mapfoldl(f::typeof(identity), op::typeof(Base.add_sum), itr::String; init::Int64)
@ Base ./reduce.jl:175 [inlined]
[7] mapreduce(f::typeof(identity), op::typeof(Base.add_sum), itr::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:307 [inlined]
[8] sum(f::typeof(identity), a::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:535 [inlined]
[9] sum(a::String; kw::@Kwargs{init::Int64})
@ Base ./reduce.jl:564 [inlined]
[10] top-level scope
@ REPL[12]:1
兼容性:Julia1.10
这个宏首先在Julia1.10中实现。 |
# *'基。Val'`-Type</no-翻译>
Val(c)
返回类型'Val{c}()`,不包含运行时数据。 此类类型可用于使用值`c`在函数之间传输信息,该值应为`isbits`或`Symbol’类型。 这种设计的目的是能够直接(在编译时)分派常量,而不必在运行时检查它们的值。
例子
julia> f(::Val{true}) = "Good"
f (generic function with 1 method)
julia> f(::Val{false}) = "Bad"
f (generic function with 2 methods)
julia> f(Val(true))
"Good"
# ’核心。Vararg'*-Constant</no-翻译>
Vararg{T,N}
元组类型的最后一个参数 'Tuple'可以有一个特殊的值’Vararg',这意味着末尾的任意数量的元素。 表达式’Vararg{T,N}'完全匹配`T’类型的`N’元素。 最后,表达式'Vararg{T}'对应于`T’类型的零个或多个元素。 带有`Vararg`参数的元组类型用于表示具有可变参数数量的方法所接受的参数(请参阅关于 具有可变参数数量的函数)。
另请参阅说明 'NTuple'。
例子
julia> mytupletype = Tuple{AbstractString, Vararg{Int}}
Tuple{AbstractString, Vararg{Int64}}
julia> isa(("1",), mytupletype)
true
julia> isa(("1",1), mytupletype)
true
julia> isa(("1",1,2), mytupletype)
true
julia> isa(("1",1,2,3.0), mytupletype)
false
# '基。isnothing'-Function
isnothing(x)
如果`x===nothing`返回`true`,否则返回`false`。
兼容性:Julia1.1
此功能需要至少1.1的Julia版本。 |
另请参阅说明 '东西', '基地。notnothing'和 'ismissing'。
# '基。东西'-Function
something(x...)
另请参阅说明 '合并`, `skipmissing'和 '@something'。
例子
julia> something(nothing, 1)
1
julia> something(Some(1), nothing)
1
julia> something(Some(nothing), 2) === nothing
true
julia> something(missing, nothing)
missing
julia> something(nothing, nothing)
ERROR: ArgumentError: No value arguments present
# '基。@something'-Macro
@something(x...)
功能的缩短版本 '东西'。
例子
julia> f(x) = (println("f($x)"); nothing);
julia> a = 1;
julia> a = @something a f(2) f(3) error("Unable to find default for `a`")
1
julia> b = nothing;
julia> b = @something b f(2) f(3) error("Unable to find default for `b`")
f(2)
f(3)
ERROR: Unable to find default for `b`
[...]
julia> b = @something b f(2) f(3) Some(nothing)
f(2)
f(3)
julia> b === nothing
true
兼容性:Julia1.7
这个宏首先在Julia1.7中实现。 |
# '基。枚举。@enum'-Macro
@enum EnumName[::BaseType] value1[=x] value2[=y]
创建`Enum的子类型{BaseType}'名称为’EnumName’和枚举元素’value1’和’value2',可分别分配值’x’和’y'。 EnumName可以以与任何其他类型相同的方式使用,并且枚举元素的值可以用作正常值。
例子
julia> @enum Fruit apple=1 orange=2 kiwi=3
julia> f(x::Fruit) = "I'm a Fruit with value: $(Int(x))"
f (generic function with 1 method)
julia> f(apple)
"I'm a Fruit with value: 1"
julia> Fruit(1)
apple::Fruit = 1
枚举元素也可以在`begin`块内指定,例如:
@enum EnumName begin
value1
value2
end
基本类型是’BaseType'(默认情况下 'Int32')必须是`Integer’类型的原始子类型。 元素的值可以在枚举类型和`BaseType’之间转换。 '读’和’写’自动执行这些转换。 如果使用默认类型以外的`BaseType`类型创建枚举,则`Integer(value1)返回具有`BaseType`类型的整数值`value1
。
要获取枚举的所有实例的列表,请使用’instances’函数,例如:
julia> instances(Fruit)
(apple, orange, kiwi)
您可以从枚举实例构造符号:
julia> Symbol(apple)
:apple
# *'核心。Expr'`-Type
Expr(head::Symbol, args...)
表示分析的Julia代码(AST)中的复合表达式的类型。 每个表达式由一个’head’部分,一个`Symbol’组成,它指定表达式的类型(例如,调用,for循环,条件运算符等)。)和子表达式(例如,调用参数)。 子表达式存储在'Vector'字段中{Any}'名称为’args'。
请参阅手册的章节 元编程和开发人员文档部分专门用于 Julia中的AST语法。
例子
julia> Expr(:call, :+, 1, 2)
:(1 + 2)
julia> dump(:(a ? b : c))
Expr
head: Symbol if
args: Array{Any}((3,))
1: Symbol a
2: Symbol b
3: Symbol c
# ’核心。符号'*-Type
Symbol
分析的Julia代码(AST)中用于表示标识符的对象类型。 它也经常用作标识实体的名称或标签(例如,作为字典键)。 'Symbol’对象可以使用quote运算符`:`输入:
julia> :name
:name
julia> typeof(:name)
Symbol
julia> x = 42
42
julia> eval(:x)
42
'Symbol’类型的对象也可以通过调用构造函数'Symbol(x)从字符串或其他值创建。..)`.
符号('Symbol`)是不可变的,它们的实现对所有具有相同名称的符号(Symbol
)使用相同的对象。
与字符串不同`"符号"是不支持字符迭代的"原子"或"标量"实体。
通用功能
# ’核心。函数'*-Type</no-翻译>
Function
所有函数的抽象类型。
例子
julia> isa(+, Function)
true
julia> typeof(sin)
typeof(sin) (singleton type of function sin, subtype of Function)
julia> ans <: Function
true
# '基。hasmethod'-Function
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool
确定给定的通用函数是否具有与参数类型的指定元组相对应的方法,并在"world"参数中指定"age of the world"(方法定义的层次结构)的上限。
如果提供了命名参数名称`kwnames`的元组,则还会检查与类型`t`对应的方法`f`以查找这些名称。 如果一个方法接受可变数量的命名参数,例如使用`kwargs。..','kwnames’中的所有名称都被认为是适当的。 否则,指定的名称必须是方法的命名参数的子集。
另请参阅说明 '适用`。
兼容性:Julia1.2
要指定命名参数的名称,需要至少1.2的Julia版本。 |
例子
julia> hasmethod(length, Tuple{Array})
true
julia> f(; oranges=0) = oranges;
julia> hasmethod(f, Tuple{}, (:oranges,))
true
julia> hasmethod(f, Tuple{}, (:apples, :bananas))
false
julia> g(; xs...) = 4;
julia> hasmethod(g, Tuple{}, (:a, :b, :c, :d)) # g принимает произвольное число именованных аргументов
true
#
'核心。适用
*-Function
applicable(f, args...) -> Bool
确定指定的通用函数是否具有适用于指定参数的方法。
另请参阅说明 'hasmethod'。
例子
julia> function f(x, y)
x + y
end;
julia> applicable(f, 1)
false
julia> applicable(f, 1, 2)
true
# '基。isambiguous`-Function
Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool
确定两个方法’m1’和’m2’对于某些调用签名是否可能不明确。 此检查是在同一函数的其他方法的上下文中执行的:方法`m1`和`m2`本身可能是不明确的,但是如果定义了解决歧义的第三种方法,则返回值`false'。 相反,方法`m1`和’m2’可以自己排序,但如果第三种方法不能与它们一起排序,则聚合中产生歧义。
对于参数类型,命名参数’ambiguous_bottom’确定联合’Union{}'是否被认为是类型参数的不明确交集:当设置为`true`时,它被认为是不明确的,但如果值为`false`,则不是。
例子
julia> foo(x::Complex{<:Integer}) = 1
foo (generic function with 1 method)
julia> foo(x::Complex{<:Rational}) = 2
foo (generic function with 2 methods)
julia> m1, m2 = collect(methods(foo));
julia> typeintersect(m1.sig, m2.sig)
Tuple{typeof(foo), Complex{Union{}}}
julia> Base.isambiguous(m1, m2, ambiguous_bottom=true)
true
julia> Base.isambiguous(m1, m2, ambiguous_bottom=false)
false
# ’核心。调用'*-Function
invoke(f, argtypes::Type, args...; kwargs...)
调用指定的通用函数`f`的方法,它对应于指定的类型`argtypes`,传递参数`args`和命名参数`kwargs'。 "Args"参数必须与"argtypes"中指定的类型匹配,这意味着不执行自动转换。 此函数允许您调用不是最具体的方法,这在显式需要更一般定义的行为的情况下很有用(通常作为同一函数的更具体方法的实现的一部分)。
当使用’invoke’调用其他人编写的函数时,请小心。 用于指定类型的’argtypes’的定义取决于内部实现,除非明确声明具有某些类型的’argtypes’的调用是公共API的一部分。 例如,在下面的示例中,函数`f1`和`f2`通常可以互换,因为在正常调用期间(不使用`invoke`)它们之间没有区别。 但是,当使用`invoke’时,这种差异变得明显。
例子
julia> f(x::Real) = x^2;
julia> f(x::Integer) = 1 + invoke(f, Tuple{Real}, x);
julia> f(2)
5
julia> f1(::Integer) = Integer
f1(::Real) = Real;
julia> f2(x::Real) = _f2(x)
_f2(::Integer) = Integer
_f2(_) = Real;
julia> f1(1)
Integer
julia> f2(1)
Integer
julia> invoke(f1, Tuple{Real}, 1)
Real
julia> invoke(f2, Tuple{Real}, 1)
Integer
# '基。@invoke`-Macro
@invoke f(arg::T, ...; kwargs...)
提供了一个方便的呼叫方式 invoke
通过扩展'@invoke f(arg1::T1,arg2::T2;kwargs。..)before'invoke(F,元组{T1,T2},arg1,arg2;kwargs...)
. 如果没有指定参数类型的注释,它将被"核心"类型替换。这个论点的类型。 若要调用其参数未键入或显式键入为"Any"的方法,请使用"::Any"注释该参数。
此外,还支持以下语法:
-
'@invoke(x::X)。f’扩展为’invoke(getproperty,Tuple{X,Symbol},x,:f)`
-
'@invoke(x::X)。f=v::V`扩展为’invoke(setproperty!,元组{X,Symbol,V},x,:f,v)`
-
@invoke(xs::Xs)[i::I]'扩展为’invoke(getindex,Tuple{Xs,I},xs,i)
-
@invoke(xs::Xs)[i::I]=v::V`扩展为’invoke(setindex!,元组{Xs,V,I},xs,v,i)
例子
julia> @macroexpand @invoke f(x::T, y)
:(Core.invoke(f, Tuple{T, Core.Typeof(y)}, x, y))
julia> @invoke 420::Integer % Unsigned
0x00000000000001a4
julia> @macroexpand @invoke (x::X).f
:(Core.invoke(Base.getproperty, Tuple{X, Core.Typeof(:f)}, x, :f))
julia> @macroexpand @invoke (x::X).f = v::V
:(Core.invoke(Base.setproperty!, Tuple{X, Core.Typeof(:f), V}, x, :f, v))
julia> @macroexpand @invoke (xs::Xs)[i::I]
:(Core.invoke(Base.getindex, Tuple{Xs, I}, xs, i))
julia> @macroexpand @invoke (xs::Xs)[i::I] = v::V
:(Core.invoke(Base.setindex!, Tuple{Xs, V, I}, xs, v, i))
兼容性:Julia1.7
此宏至少需要Julia的1.7版本。 |
兼容性:Julia1.9
此宏自Julia1.9版本开始导出。 |
兼容性:Julia1.10
自Julia1.10以来,其他语法一直受到支持。 |
# '基。invokelatest'-Function
invokelatest(f, args...; kwargs...)
调用'f(args...;夸格斯。..)`,但保证执行最近的方法’f'。 这在特殊情况下很有用,例如在执行可能调用过时版本的`f`函数的长事件循环或回调函数时。 (缺点是’invokelatest’函数比直接调用`f`稍慢,编译器无法推断结果类型。)
兼容性:Julia1.9
在Julia1.9之前,此函数未导出,并以`Base的形式调用。invokelatest'。 |
# '基。@invokelatest'-Macro
@invokelatest f(args...; kwargs...)
提供了一个方便的呼叫方式 'invokelatest'。 '@invokelatest f(args。..;夸格斯。..)'只是扩展到'Base。invokelatest(f,args...;夸格斯。..)`.
此外,还支持以下语法:
-
'@invokelatest x.f’扩展为’Base。invokelatest(getproperty,x,:f)`
-
'@invokelatest x.f=v’扩展为’Base。invokelatest(setproperty!,x,:f,v)`
-
'@invokelatest xs[i]
扩展为’Base。invokelatest(getindex,xs,i)
-
'@invokelatest xs[i]=v`扩展为`Base。invokelatest(setindex!,xs,v,i)`
julia> @macroexpand @invokelatest f(x; kw=kwv)
:(Base.invokelatest(f, x; kw = kwv))
julia> @macroexpand @invokelatest x.f
:(Base.invokelatest(Base.getproperty, x, :f))
julia> @macroexpand @invokelatest x.f = v
:(Base.invokelatest(Base.setproperty!, x, :f, v))
julia> @macroexpand @invokelatest xs[i]
:(Base.invokelatest(Base.getindex, xs, i))
julia> @macroexpand @invokelatest xs[i] = v
:(Base.invokelatest(Base.setindex!, xs, v, i))
兼容性:Julia1.7
此宏至少需要Julia的1.7版本。 |
兼容性:Julia1.9
在Julia1.9之前,此宏未导出,并以"Base"形式调用。@invokelatest'。 |
兼容性:Julia1.10
对于`x.f`和`xs[i]`的附加语法,需要版本Julia1.10。 |
# '基。:`>'-Function</no-翻译>
|>(x, f)
将函数`f`应用于参数`x’的中缀运算符。 这允许您以`x|>g|>f`的形式编写`f(g(x))`。 使用匿名函数时,通常需要将定义括在括号中,以便获得所需的链。
例子
julia> 4 |> inv
0.25
julia> [2, 3, 5] |> sum |> inv
0.1
julia> [0 1; 2 3] .|> (x -> x^2) |> sum
14
# *'基。:∘'`-Function</no-翻译>
f ∘ g
函数组成’(f∈g)(args...;夸格斯。..)'表示'f(g(args...;夸格斯。..)). 字符'∘'可以通过键入
\circ<tab>`添加到Julia的REPL(以及相应配置的大多数编辑器)中。
函数组合也可以采用前缀形式:'∘(f,g)相当于`f∘g'。 前缀形式支持几个函数('∘(f,g,h)=f∘g∘h
)和解压(∘(fs。..)
)来创建函数的可迭代集合。 `∘`的最后一个参数首先执行。
兼容性:Julia1.4
几个函数的组成需要至少1.4的Julia版本。 |
兼容性:Julia1.5
单个函数∘(f)的组成需要1.5或更高的Julia版本。 |
兼容性:Julia1.7
使用命名参数需要至少1.7的Julia版本。 |
例子
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Vector{Char}:
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)
julia> (==(6)∘length).(["apple", "banana", "carrot"])
3-element BitVector:
0
1
1
julia> fs = [
x -> 2x
x -> x-1
x -> x/2
x -> x+1
];
julia> ∘(fs...)(3)
2.0
另请参阅说明 'ComposedFunction'和 `!f::函数'。
# '基。ComposedFunction'-Type
ComposedFunction{Outer,Inner} <: Function
表示两个被称为对象`outer::Outer`和`inner::Inner`的组合。 这就是
ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))
要创建’ComposedFunction’类型的实例,最好使用composition运算符。 ∘
:
julia> sin ∘ cos === ComposedFunction(sin, cos)
true
julia> typeof(sin∘cos)
ComposedFunction{typeof(sin), typeof(cos)}
组合的组件存储在’ComposedFunction’对象的字段中。 它们可以按如下方式访问。
julia> composition = sin ∘ cos
sin ∘ cos
julia> composition.outer === sin
true
julia> composition.inner === cos
true
兼容性:Julia1.6
要使用ComposedFunction类型,需要Julia1.6或更高版本。 在早期版本中,`∘`运算符返回一个匿名函数。 |
另请参阅说明 ∘
.
# '基。splat'-Function
splat(f)
相当于
my_splat(f) = args->f(args...)
也就是说,如果给定一个函数,它返回一个新函数,该函数接受一个参数并将其解压缩到原始函数中。 如果您需要在需要单个参数的上下文中传递具有多个参数的函数,这可能很有用;但是元组作为该参数传递。
例子
julia> map(splat(+), zip(1:3,4:6))
3-element Vector{Int64}:
5
7
9
julia> my_add = splat(+)
splat(+)
julia> my_add((1,2,3))
6
语法
# ``eval'*-Function
eval(expr)
计算包含模块全局作用域中的表达式。 每个’模块`(除了用关键字’baremodule’声明的模块)都有自己的`eval`函数定义,其中有一个参数,用于计算此模块中的表达式。
# '基。evalfile'—Function
evalfile(path::AbstractString, args::Vector{String}=String[])
使用函数将文件上传到匿名模块 `include',计算所有表达式并返回最后一个表达式的值。 可选参数"args"可用于指定脚本的输入参数(即全局变量"ARGS")。 请注意,定义(例如,方法,全局对象)在匿名模块中处理,并且不会影响当前模块。
例子
julia> write("testfile.jl", """
@show ARGS
1 + 1
""");
julia> x = evalfile("testfile.jl", ["ARG1", "ARG2"]);
ARGS = ["ARG1", "ARG2"]
julia> x
2
julia> rm("testfile.jl")
# '基。@inbounds'-Macro
@inbounds(blk)
禁用检查表达式中数组的边界。
在下面的示例中,在访问数组`A`的元素`i`时跳过范围条目检查以提高性能。
function sum(A::AbstractArray)
r = zero(eltype(A))
for i in eachindex(A)
@inbounds r += A[i]
end
return r
end
使用'@inbounds’宏时,如果索引超出数组的边界,可能会返回不正确的结果,崩溃或数据损坏。 用户必须手动执行验证。 只有当宏`@inbounds`从本地上下文清楚地遵循所有访问都将在边界内发生时,才使用宏'@inbounds'。 特别是,在像上面这样的函数中使用`1:length(A) |
# '基。@boundscheck'-Macro
@boundscheck(blk)
将表达式`blk’标记为边界检查块,因此它可以被块忽略。 '@inbounds'。
定义'@boundscheck’块的函数必须嵌入到调用对象中,才能使`@inbounds’宏工作。 |
例子
julia> @inline function g(A, i)
@boundscheck checkbounds(A, i)
return "accessing ($A)[$i]"
end;
julia> f1() = return g(1:2, -1);
julia> f2() = @inbounds return g(1:2, -1);
julia> f1()
ERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]
Stacktrace:
[1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:455
[2] checkbounds at ./abstractarray.jl:420 [inlined]
[3] g at ./none:2 [inlined]
[4] f1() at ./none:1
[5] top-level scope
julia> f2()
"accessing (1:2)[-1]"
|
# '基。@inline'-Macro
@inline
给编译器一个可以嵌入此函数的指示.
小函数通常不需要"@inline"注释,因为编译器会自动嵌入它们。 通过对更复杂的函数使用'@inline',您可以给编译器一个额外的信号来嵌入它们。
宏'@inline’可以在函数定义之前或在其主体中应用。
# аннотирование полного определения
@inline function longdef(x)
...
end
# аннотирование краткого определения
@inline shortdef(x) = ...
# аннотирование анонимной функции, создаваемой с помощью блока `do`
f() do
@inline
...
end
兼容性:Julia1.8
在函数体中使用至少需要1.8的Julia版本。 |
@inline block
给编译器一个指示,说明可以嵌入"块"块内的调用。
# Компилятор попытается встроить `f`
@inline f(...)
# Компилятор попытается встроить `f`, `g` и `+`
@inline f(...) + g(...)
调用位置的注释始终优先于应用于被调用函数定义的注释。: |
@noinline function explicit_noinline(args...)
# тело
end
let
@inline explicit_noinline(args...) # будет встроено
end
如果调用位置有嵌套注释,则嵌套最深的注释优先。: |
@noinline let a0, b0 = ...
a = @inline f(a0) # компилятор попытается встроить этот вызов
b = f(b0) # компилятор НЕ будет пытаться встроить этот вызов
return a, b
end
虽然如果在调用位置有注释,则会在不考虑成本模型的情况下进行嵌入尝试,但有可能不会发生嵌入。 特别是,递归调用不能嵌入,即使它们用`@inline’注释。 |
兼容性:Julia1.8
要在调用位置使用注释,需要至少1.8的Julia版本。 |
# '基。@noinline'-Macro
@noinline
给编译器一个不应该嵌入函数的指示.
小功能通常是自动集成的。 通过将宏`@noinline’应用于它们,您可以防止这种情况。
宏'@noinline’可以在函数定义之前或在其主体中应用。
# аннотирование полного определения
@noinline function longdef(x)
...
end
# аннотирование краткого определения
@noinline shortdef(x) = ...
# аннотирование анонимной функции, создаваемой с помощью блока `do`
f() do
@noinline
...
end
兼容性:Julia1.8
在函数体中使用至少需要1.8的Julia版本。 |
@noinline block
给编译器一个指示,说明不应该嵌入"块"块内的调用。
# Компилятор попытается не встраивать `f`
@noinline f(...)
# Компилятор попытается не встраивать `f`, `g` и `+`
@noinline f(...) + g(...)
调用位置的注释始终优先于应用于被调用函数定义的注释。: |
@inline function explicit_inline(args...)
# тело
end
let
@noinline explicit_inline(args...) # не будет встроено
end
如果调用位置中有嵌套注释,则嵌套最深的注释优先。: |
@inline let a0, b0 = ...
a = @noinline f(a0) # компилятор НЕ будет пытаться встроить этот вызов
b = f(b0) # компилятор попытается встроить этот вызов
return a, b
end
兼容性:Julia1.8
要在调用位置使用注释,需要至少1.8的Julia版本。 |
最简单的函数(例如,返回一个常量)可以嵌入,尽管有注释。 |
# '基。@nospecialize'-Macro
@nospecialize
当应用于函数参数名称时,它指示编译器该方法不应专门用于此参数的不同类型:声明的类型应用于每个参数。 它可以应用于形式参数列表或函数体中的参数。 当应用于参数时,宏必须复盖其整个表达式,例如`@nospecialize(x::Real)或
+@nospecialize(i::Integer)。..)+`,而不仅仅是参数的名称。 在函数体中使用时,宏必须位于代码其余部分之前的运算符位置。
在没有参数的情况下使用时,此宏适用于父作用域中的所有参数。 在局部作用域中,这意味着包含函数的所有参数。 在全局区域(顶层)中,这意味着在当前模块中进一步定义的所有方法。
您可以使用宏还原默认的特化行为 '@specialty'。
function example_function(@nospecialize x)
...
end
function example_function(x, @nospecialize(y = 1))
...
end
function example_function(x, y, z)
@nospecialize x y
...
end
@nospecialize
f(y) = [x for x in y]
@specialize
|
例子
julia> f(A::AbstractArray) = g(A)
f (generic function with 1 method)
julia> @noinline g(@nospecialize(A::AbstractArray)) = A[1]
g (generic function with 1 method)
julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Float64
└── return %1
) => Float64
在这里,注释'@nospecialize’的结果是等价的
f(A::AbstractArray) = invoke(g, Tuple{AbstractArray}, A)
确保只为`g’生成一个版本的机器代码,这对于任何`AbstractArray’数组都是通用的。 但是,对于`g’和’f`,定义了一个特定的返回类型,它仍然用于优化`f`和’g’的调用者。
# '基。@nospecializeinfer'-Macro
Base.@nospecializeinfer function f(args...)
@nospecialize ...
...
end
Base.@nospecializeinfer f(@nospecialize args...) = ...
指示编译器使用宏"@nospecialize"应用到的声明参数类型输出类型"f"。 它可用于限制编译器在输出期间生成的特化的数量。
例子
julia> f(A::AbstractArray) = g(A)
f (generic function with 1 method)
julia> @noinline Base.@nospecializeinfer g(@nospecialize(A::AbstractArray)) = A[1]
g (generic function with 1 method)
julia> @code_typed f([1.0])
CodeInfo(
1 ─ %1 = invoke Main.g(_2::AbstractArray)::Any
└── return %1
) => Any
在这个例子中,类型`f`将为每个特定类型`A`输出,但类型`g`将只输出一次与声明的参数类型`A::AbstractArray'。 这意味着编译器对它的输出时间很可能不会增加,因为不可能推导出特定的返回类型。 如果未使用宏`@nospecializeinfer`,则对于’f([1.0]),将输出返回类型`g``Float64',即
g(::Vector'的类型输出{Float64}尽管禁止生成专用代码,但仍会执行`。
兼容性:Julia1.10
以使用’基地。@nospecializeinfer’需要版本Julia1.10。 |
# '基。@constprop'-Macro
Base.@constprop setting [ex]
控制带注释函数的常量的过程间分布模式。
支持两个"设置"值:
-
"基地。@constprop:aggressive[ex]`:常量的传播以aggressive模式应用。 对于返回类型取决于参数值的方法,这可以改善输出结果,但代价是额外的编译时间。
-
"基地。@constprop:none[ex]':常量传播被禁用。 这可以减少Julia编译器可能认为适合分发常量的函数的编译时间。 典型的情况是具有参数的函数,如`Bool’或’Symbol’或命名参数。
"基础"宏。@constprop’可以立即在函数定义之前或在其主体中应用。
# аннотирование полного определения
Base.@constprop :aggressive function longdef(x)
...
end
# аннотирование краткого определения
Base.@constprop :aggressive shortdef(x) = ...
# аннотирование анонимной функции, создаваемой с помощью блока `do`
f() do
Base.@constprop :aggressive
...
end
兼容性:Julia1.10
在函数体中使用Julia至少需要1.10的版本。 |
# 'var"name"'-Keyword
var
语法’var"example"'允许您访问名为`Symbol("example")'的变量,即使`example`在Julia中不是有效的名称。
这对于与具有用于构造有效名称的不同规则的编程语言的兼容性非常有用。 例如,访问名为"draw"的"R"变量。段`,可以使用表达式’var"绘制。段"'中的Julia代码。
此外,它用于显示(`show')经过卫生宏处理或以其他方式包含无法以通常方式分析的变量名称的Julia源代码。
请注意,此语法需要分析器支持,因此它由分析器直接扩展,而不是作为常规字符串宏`@var_str’实现。
兼容性:Julia1.3
使用此语法需要至少1.3的Julia版本。 |
# '基。辛德鲁普。@simd`-Macro
@simd
标记循环’for`,告诉编译器它可以更自由地重新排序。
此功能是实验性的,可能会在Julia的未来版本中更改或消失。 不正确使用`@simd’宏可能会导致意外结果。 |
正在`@simd for`循环中迭代的对象必须是一维范围。 当使用宏'@simd`时,会断言几个循环属性。
-
迭代可以以任何顺序或重叠安全地执行(具有缩减变量的操作具有自己的特征)。
-
使用减少变量执行的浮点运算的顺序可以更改或缩短,结果可能与不使用`@simd’的情况不同。
在许多情况下,Julia可以自动矢量化内部for循环,而无需使用'@simd`宏。 使用'@simd’给编译器额外的自由,因此矢量化在其他情况下也是可能的。 无论如何,要对内循环进行矢量化,它必须具有以下属性。
-
循环应该是嵌套最深的。
-
循环的主体应该是线性代码。 因此,目前 '@inbounds'所有对数组的访问都需要。 编译器有时可以转换短表达式'&&',|//
和
?:'成线性代码,如果它是安全的评估所有操作数没有条件。 您也可以使用该功能ifelse'
而不是?:'在循环中,如果这样做是安全的。 -
请求必须是一步一步的:禁止"构建"(在任意索引处读取)和"分发"(在任意索引处写入)操作。
-
阵列的步骤必须是单一的。
默认情况下,`@simd’宏不会断言循环在内存中完全没有循环生成的依赖关系:在广义代码中,这种假设很容易被违反。 如果您正在编写非共享代码,则可以使用'@simd ivdep for。.. 结束'以批准以下附加条件。 |
-
内存中没有循环生成的依赖关系。
-
任何迭代都可以向前移动,而无需等待上一个迭代完成。
# '基。@generated'-Macro
@generated f
'@generated’将函数标记为已生成。 在生成的函数的主体中,只有参数类型可用(但不能使用它们的值)。 函数返回在调用函数时计算的带引号的表达式。 '@Generated’宏不应应用于更改全局作用域或依赖于可变元素的函数。
有关更多信息,请参阅 元编程。
例子
julia> @generated function bar(x)
if x <: Integer
return :(x ^ 2)
else
return :(x)
end
end
bar (generic function with 1 method)
julia> bar(4)
16
julia> bar("baz")
"baz"
# '基。@assume_effects'-Macro
Base.@assume_effects setting... [ex]
重新定义编译器的副作用模型。 此宏可用于多种上下文。:
-
紧接在定义方法之前重新定义所应用方法的整个副作用模型;
-
在没有参数的函数体内部重新定义封闭方法的整个副作用模型;
-
应用于代码块,用于重新定义其局部副作用模型。
例子
julia> Base.@assume_effects :terminates_locally function fact(x)
# вариант использования 1:
# :terminates_locally обеспечивает свертку констант в `fact`
res = 1
0 ≤ x < 20 || error("bad fact")
while x > 1
res *= x
x -= 1
end
return res
end
fact (generic function with 1 method)
julia> code_typed() do
fact(12)
end |> only
CodeInfo(
1 ─ return 479001600
) => Int64
julia> code_typed() do
map((2,3,4)) do x
# вариант использования 2:
# :terminates_locally обеспечивает свертку констант в анонимной функции
Base.@assume_effects :terminates_locally
res = 1
0 ≤ x < 20 || error("bad fact")
while x > 1
res *= x
x -= 1
end
return res
end
end |> only
CodeInfo(
1 ─ return (2, 6, 24)
) => Tuple{Int64, Int64, Int64}
julia>code_typed()do
地图((2,3,4))做x
res=1
0≤x<20//错误("坏事实")
#用例3:
#摘要:terminates_locally表示编译器不应执行分析
#在这个提供卷积的"while"块中终止"效果
#父匿名函数中的常量
基地。@assume_effects:当x>1时terminates_locally
res*=x
x-=1
结束
返回res
结束
结束/>只
代码信息(
1─返回(2,6,24)
)=>元组{Int64, Int64, Int64}
兼容性:Julia1.8
以使用’基地。@estime_effects的版本Julia1.8是必需的。 |
兼容性:Julia1.10
在函数体中使用Julia至少需要1.10的版本。 |
兼容性:Julia1.11
要注释代码块,需要至少1.11的Julia版本。 |
不当使用此宏可能会导致未定义的行为(包括崩溃,不正确的结果或其他难以跟踪的错误)。 谨慎使用,只有在绝对必要时才使用。 即使在这种情况下,也应该采取所有可能的措施来尽量减少副作用陈述的严重程度(例如,不要使用`:total`if`:nothing`就足够了)。 |
通常,每个"设置"值都会对函数的行为做出声明,而不需要编译器确认这样的值。 这样的声明是为所有"世界的年龄。"因此,建议避免使用以后可以扩展的泛型函数,以便语句变得无效(导致未定义的行为)。
支持以下"设置"值:
-
':一致`
-
`:effect_free'
-
`:nothrow'
-
':终止_全球范围`
-
':终止_locally`
-
:notaskstate
-
`:inconcessiblemonly'
-
:noub
-
':noub_if_noinbounds`
-
:nortcall
-
:可折叠
-
:可拆卸
-
':总计`
高级帮助
':一致`
值':consistent’为相同的输入数据断言以下内容('===`):
-
执行完成的方式(返回值、调用异常或未完成执行)将始终相同。;
-
如果该方法返回control,则结果将始终相同。
特别是,它遵循的方法不应该返回一个新分配的可变对象。 存储在内存中不同位置的可变对象是不相同的,即使它们的内容是相同的。 |
`:一致’的说法是考虑到"世界的时代"而作出的。 更正式地说,这表示如下:如果有 来计算 在"和平时代" 以下必须为真: |
Однако для двух «возрастов мира» ``i`` и ``j``, таких что ``i ≠ j``, возможно, что ``fᵢ(x) ≢ fⱼ(y)``. Из этого далее следует, что возвращаемые значения функций `:consistent` не должны зависеть от состояния кучи или любого другого состояния, которое не является постоянным для данного «возраста мира».
':Consistent’语句适用于优化器执行的所有有效代码修订。 例如,fastmath浮点运算不被认为与`:consistent`语句一致,因为优化器可能会过度使用它们,导致即使对于相同的"世界时代"也不一致的输出( |
如果`:consistent`函数的执行以异常结束,则不需要该异常本身来满足上述身份要求。 |
`:effect_free'
值`:effect_free’断言该方法没有外部语义上可见的副作用。 以下是此类影响的不完整列表:
-
更改全局变量的值;
-
更改堆(例如,数组或可变值),以下指定的情况除外;
-
更改方法表(例如,通过调用eval函数);
-
I/O操作(文件、网络等));
-
切换任务。
然而,以下副作用在语义上并不清晰可见,即使可以观察到:
-
内存分配(可变和不可变对象);
-
经过的时间;
-
垃圾收集;
-
修改堆中的对象,其生存期不超过方法的执行时间(即它们被放置在方法中的内存中并且不离开它);
-
返回一个值(从外部可见,但不是副作用)。
简而言之,外部可见的副作用是如果函数未执行,则会影响程序其余部分的执行。
语句':effect_free’既针对方法本身,也针对它执行的所有代码。 请注意,对于所有"世界年龄"都必须遵循此声明,因此应以有限的方式应用。 |
`:nothrow'
值`:nothing’断言此方法的执行不会导致异常(即,该方法要么始终返回值,要么从不返回控件)。
异常处理可以在带有`:nothrow`注解的方法内部使用,但是异常不应该从方法本身传递。 |
如果执行一个方法会导致’MethodError’和其他类似的异常,那么该方法不被视为':nothing'。 但是,请注意,依赖于环境的错误`如’StackOverflowError’或’InterruptException’不是由此副作用建模的。 因此,可能导致’StackOverflowError’的方法不必是'!:nothrow'(虽然它通常也必须是'!:终止')。 |
':terminates_globally`
值`:terminates_globally’断言此方法的执行最终完成(有或没有错误),即它不会进入无限循环。
语句':terminates_globally’适用于被注释方法调用的所有其他方法。 |
编译器将此语句视为方法的执行将相对快速完成的明确标志,并且可以(如果允许)在编译期间调用此方法。 因此,将这种注释提供给理论上应该完成其执行的方法是不可取的,但在实践中可能不会发生这种情况。 |
':terminates_locally`
:Terminates_locally’的值类似于
:terminates_globally’的值,不同之处在于它仅适用于注释方法的语法执行顺序。 因此,这是一个不那么严格(因此更安全)的语句,如果它以被调用的另一个方法为条件,则允许无限执行的可能性。
语句`:terminates_globally’表示':terminates_locally'。 |
':notaskstate`
`:Notaskstate’参数声明该方法不使用或修改本地任务的状态(任务本地存储,RNG状态等。),因此可以安全地在任务之间移动而没有明显的结果。
异常处理实现使用任务对象中存储的状态。 但是,此状态目前不被认为在`:notaskstate’的范围内,并且使用副作用`:notrow’单独监控。 |
语句':notaskstate’是指当前正在运行的task_的状态。 如果对`Task`对象的引用是以不考虑当前执行任务的方式的其他方式获得的,则`:notaskstate’效果不需要被"污染"。 如果任务对象在编程上与当前正在运行的任务相同( |
访问任务状态通常还会导致"污染"其他效果,例如`:effect_free`(如果任务状态发生变化)或`:consistent`(如果任务状态用于计算结果)。 特别是,没有`:notaskstate`效果,但具有`:effect_free`和`:consistent`效果的代码仍然可能被排除在非工作代码之外,从而获得`:total`效果。 |
':无法理解`
`:Inaccessiblemonly’参数声明该方法不访问或修改外部可访问的可变内存。 这意味着方法可以访问或修改新分配的对象的可变内存,这些对象在从方法返回之前对其他方法或顶级执行不可用,但它不能访问或修改其参数指向的任何可变全局状态或可变内存。
下面是一个不完整的示例列表,其中这个假设是不正确的:--全局引用或调用’getglobal’来访问可变全局变量;--全局赋值或调用`setglobal!'执行对非常量全局变量的赋值;--call’setfield!`,其修改全局可变变量的字段。 |
语句`:unaccessiblemonly’适用于被注释方法调用的所有其他方法。 |
':noub`
:Noub’参数声明该方法不会以无限期的方式执行(对于任何输入数据)。 请注意,未定义行为在技术上会导致方法违反其他副作用语句(例如,
:consistent`或`:effect_free`),但是,不会对这种情况进行建模,并且假定不存在未定义行为。
':nortcall`
`:Nortcall’参数声明该方法不调用’Core。编译器。return_type’并且此方法可能调用的任何其他方法也不调用`Core。编译器。return_type'。
更准确地说,在调用’Core时可以使用此语句。编译器。return_type`不在运行时产生,即当结果为’Core时。编译器。return_type’在编译时确切地知道,并且优化器排除了调用。 然而,由于结果的卷积是’核心。编译器。在编译时return_type’高度依赖于编译器实现,如果所讨论的方法使用`Core,则断言此通常是有风险的。编译器。return_type`以某种形式。 |
':可折叠`
该值是一组必须保证的副作用的方便简写,以便编译器可以执行要在编译时调用的常量的卷积。 它目前相当于`setting`的以下值:
-
':一致`
-
`:effect_free'
-
':终止_全球范围`
-
:noub
-
:nortcall
此列表中缺少语句`:nothing'。 编译器将尝试在编译期间执行常量替换,并记录发生的任何错误。 但是,请记住,根据`:consistent’语句的要求,任何具有此类注释的调用都应该产生具有相同参数值的相同错误。 |
在函数内部显式注释`@inbounds’也将禁用常量的折叠,并且不会被`:folding`参数复盖。 |
':可拆卸`
此值是一组必须保证的副作用的方便简写,以便编译器可以删除其结果在编译时未使用的调用。 它目前相当于`setting`的以下值:
-
`:effect_free'
-
`:nothrow'
-
':终止_全球范围`
':总计`
此"设置"值表示最完整的副作用集。 它目前相当于`setting`的以下值:
-
':一致`
-
`:effect_free'
-
`:nothrow'
-
':终止_全球范围`
-
:notaskstate
-
`:inconcessiblemonly'
-
:noub
-
:nortcall
|
消除副作用
副作用的名称可以前缀为'!`. 这意味着必须从先前定义的元效应中排除该效应。 例如’:总计!:nothing’表示所有语句都适用于调用,但可能会失败。
管理退出使用
# '基。@弃用`-Macro</no-翻译>
@deprecate old new [export_old=true]
从使用中删除"旧"方法,用"新"调用替换它,在过程中定义一个具有指定签名的新"旧"方法。
要禁止导出’old’方法,请将`export_old`设置为`false`。
另请参阅说明 '基地。depwarn(’。
兼容性:Julia1.5
自Julia1.5以来,使用`@deprecate`宏定义的函数在运行没有设置`--depwarn=yes`标志的`julia`时不会显示警告,因为`--depwarn`参数默认设置为`no'。 使用`Pkg运行测试时会显示警告。考()'。 |
例子
julia> @deprecate old(x) new(x)
old (generic function with 1 method)
julia> @deprecate old(x) new(x) false
old (generic function with 1 method)
对没有显式类型注释的"@deprecate"宏的调用将定义过时的方法,这些方法接受任意数量的"Any"类型的位置参数和命名参数。
兼容性:Julia1.9
当自Julia1.9以来没有显式类型注释时,命名参数会被重定向。 在旧版本中,您可以通过调用`@deprecate old(args...;夸格斯。..)新(args。..;夸格斯。..)`. |
要限制使用特定签名的输出,请注释"旧"方法的参数。 例如:
julia> new(x::Int) = x;
julia> new(x::Float64) = 2x;
julia> @deprecate old(x::Int) new(x);
朱莉娅>方法(旧)
#1来自Main的旧通用函数的方法:
[1]旧(x::Int64)
@弃用。jl:94
定义和禁用’old(x’方法。::Int)`,这是`new(x::Int)`的镜像,但不会定义或禁用`old(x’方法。::Float64’。
# '基。depwarn'-Function
Base.depwarn(msg::String, funcsym::Symbol; force=false)
输出"msg"消息作为关于退役的警告。 符号’funcsym’必须是调用函数的名称,以便每个调用位置只显示一次有关停用的警告。 为了确保始终显示警告,即使Julia环境以`--depwarn=no`(默认情况下)启动,也要设置’force=true'。
另请参阅说明 '@弃用'。
例子
function deprecated_func()
Base.depwarn("Don't use `deprecated_func()`!", :deprecated_func)
1 + 1
end
缺失值
# '基。缺少'-Type
Missing
没有字段的类型,其唯一实例是 — 'missing'--用于表示缺失值。
另请参阅说明 'skipmissing', 'nonmissingtype', '没什么`。
# '基。缺少'-Constant</no-翻译>
missing
类型的唯一实例 'Missing',表示缺失值。
另请参阅说明 '南', 'skipmissing', 'nonmissingtype'。
# '基。coalesce'-Function
coalesce(x...)
返回不等于的参数值中的第一个 '失踪`,如果有的话。 否则,它返回’missing'。
另请参阅说明 'skipmissing', '东西'和 '@coalesce'。
例子
julia> coalesce(missing, 1)
1
julia> coalesce(1, missing)
1
julia> coalesce(nothing, 1) # возвращает `nothing`
julia> coalesce(missing, missing)
missing
# '基。@coalesce'-Macro
@coalesce(x...)
功能的缩短版本 '聚结`。
例子
julia> f(x) = (println("f($x)"); missing);
julia> a = 1;
julia> a = @coalesce a f(2) f(3) error("`a` is still missing")
1
julia> b = missing;
julia> b = @coalesce b f(2) f(3) error("`b` is still missing")
f(2)
f(3)
ERROR: `b` is still missing
[...]
兼容性:Julia1.7
这个宏首先在Julia1.7中实现。 |
# '基。skipmissing'-Function
skipmissing(itr)
返回`itr`参数元素的迭代器,跳过值 '失踪`。 如果对象`itr`支持索引,则可以通过对象’itr’的索引访问返回对象的元素。 不允许与缺失值对应的索引。:它们被函数跳过 '钥匙'和 'eachindex',并且当尝试使用它们时,发生’MissingException'。
使用方法 'collect'获取包含`itr`中除`missing’以外的值的数组(`Array')。 请注意:即使’itr’是一个多维数组,结果将始终是`Vector`类型,因为在保留输入数组维度的同时不可能删除缺失值。
另请参阅说明 '合并`, `ismissing'和 '东西'。
例子
julia> x = skipmissing([1, missing, 2])
skipmissing(Union{Missing, Int64}[1, missing, 2])
julia> sum(x)
3
朱莉娅>x[1]
1
朱莉娅>x[2]
错误:MissingException:缺少index(2,)处的值
[...]
朱莉娅>argmax(x)
3
朱莉娅>收集(钥匙(x))
2元素向量{Int64}:
1
3
朱莉娅>收集(skipmissing([1,失踪,2]))
2元素向量{Int64}:
1
2
朱莉娅>收集(skipmissing([1失踪;2失踪]))
2元素向量{Int64}:
1
2
# '基。nonmissingtype'-Function
nonmissingtype(T::Type)
如果’T’是包含类型’Missing’的类型联合,则返回没有`Missing`的新类型。
例子
julia> nonmissingtype(Union{Int64,Missing})
Int64
julia> nonmissingtype(Any)
Any
兼容性:Julia1.3
自Julia1.3以来,此函数已导出。 |
系统
# '基。运行'-Function
run(command, args...; wait::Bool = true)
执行用反撇号括起来的命令对象(请参阅 外部程序的实现,在手册中)。 如果出现任何问题,包括进程以非零状态终止(当’wait`参数为true时),它将返回错误。
参数是'args。..'允许您以与标准Unix文件描述符相同的顺序将文件描述符传递给命令(例如,stdin,stdout,stderr,FD(3),FD(4)。..
).
如果’wait’参数为false,则进程异步运行。 您可以等待它完成并通过对返回的进程对象调用`success`来检查其退出状态。
当’wait’参数设置为false时,进程的I/O流被路由到’devnull'。 当’wait’参数设置为true时,i/O线程与父进程共享。 要控制I/O重定向,请使用以下方法 '管道'。
# '基。devnull'-Constant
devnull
重定向流时使用:将删除写入devnull的所有数据。 相当于Unix上的`/dev/null`或Windows上的`NUL`。 使用:
run(pipeline(`cat test.txt`, devnull))
# '基。kill'—Method
kill(p::Process, signum=Base.SIGTERM)
向进程发送信号。 默认情况下,它会终止进程。 如果进程已结束,则成功返回control,但如果由于任何原因(例如,由于缺少必要的权限)无法完成进程,则返回错误。
# '基。系统。set_process_title'-Function
Sys.set_process_title(title::AbstractString)
设置进程标头。 在某些操作系统中,这是一个空闲操作。
# '基。Cmd'-Type</no-翻译>
Cmd(cmd::Cmd; ignorestatus, detach, windows_verbatim, windows_hide, env, dir)
Cmd(exec::Vector{String})
从"cmd"创建一个表示外部程序及其参数的"Cmd"对象,指定可选命名参数的值:
-
'ignorestatus::Bool`:如果值设置为`true`(默认为`false`),则`Cmd`对象不会在非零返回代码的情况下发出错误。
-
'detach::Bool':如果值设置为’true`(默认为’false`),则`Cmd`对象将在新的进程组中执行,因此在`julia’进程完成并且CTRL+C中断不会传递给它之后,它可以继续存在。
-
'windows_verbatim::Bool`:如果值设置为`true'(默认为`false'),那么在Windows中,
Cmd`对象将向进程发送命令行,而不会将参数括在引号中或转义它们,即使参数包含空格。 (在Windows中,参数作为单个命令行传递给程序,程序本身负责分析参数。 默认情况下,空参数和命令行上带有空格或制表符的参数用双引号(
“)括起来,反斜杠放在字符`\`和”`之前。 'Windows_verbatim=true’参数对于运行以非标准方式分析命令行的程序非常有用。)它仅在Windows操作系统中有效。 -
'windows_hide::Bool`:如果值设置为`true'(默认为`false`),则在Windows中执行`Cmd`对象时不会显示新的控制台窗口。 如果控制台已经打开,或者在Windows以外的系统上,它不起作用。
-
'env':指定执行’Cmd’对象时使用的环境变量。 'env’要么是带有字符串键和值的字典,要么是形式为`"var=val"`的字符串数组,要么是对的数组或元组`+"var"⇒val+
。 要更改(而不是替换)现有环境,请使用`copy(ENV)`初始化`env
,然后根据需要设置`env["var"]=val`。 要在不替换所有元素的情况下将新块添加到`Cmd`对象的环境中,请使用函数 'addenv(’。 它返回带有更新环境的’Cmd’对象。 -
`dir::AbstractString':指定命令的工作目录(而不是当前目录)。
如果没有指定命名参数,则使用`cmd’中的当前值。
请注意,构造函数是’Cmd(exec’不会创建’exec’的副本。 所有后续的’exec’更改都将反映在’Cmd’对象中。
构造"Cmd"对象的最常用方法是使用命令文本(反向撇号),例如:
`ls -l`
然后可以将对象传递给’Cmd’构造函数以更改参数,例如:
Cmd(`echo "Hello world"`, ignorestatus=true, detach=false)
# '基。setenv'-Function
setenv(command::Cmd, env; dir)
指定执行指定的`命令’时使用的环境变量。 'env’要么是一个带有字符串键和值的字典,要么是一个以`"var=val"`形式的字符串数组,要么是零个或几个以`+"var"⇒val+`对形式的参数。 要更改(而不是替换)现有环境,请使用`copy(ENV)`创建`env',然后根据需要设置`env["var"]=val',或者使用函数 'addenv'。
使用命名的’dir’参数,您可以指定命令的工作目录。 默认情况下,`dir`参数等于`command’的’dir’当前设置值(即当前工作目录,如果此值尚未重新定义)。
# '基。setcpuaffinity'-Function
setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd
将"命令"命令的CPU绑定设置为CPU Id"cpu"列表(从1开始)。 如果为"original_command"命令配置了CPU绑定,则传递值"cpu=nothing"将取消CPU绑定。
此功能仅在Linux和Windows上受支持。 MacOS上不支持它,因为libuv库不支持绑定配置。
兼容性:Julia1.8
此功能需要至少1.8的Julia版本。 |
例子
在Linux上,您可以使用taskset命令行程序查看setcpuaffinity函数的工作原理。
julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
pid 2273's current affinity mask: 13
请注意:掩码值'13’表示启用第一位,第二位和第五位(如果从最低位数开始计数):
julia> 0b010011
0x13
# '基。流水线'-Method
pipeline(from, to, ...)
创建从数据源到目标对象的管道。 源和目标对象可以是命令、输入/输出流、字符串或对管道方法的其他调用的结果。 至少有一个参数必须是命令。 字符串是文件名。 如果有两个以上的参数,则它们从左到右串联。 例如,'pipeline(a,b,c)`相当于`pipeline(pipeline(a,b),c)'。 这使您可以更简洁地定义多阶段管道。
例子:
run(pipeline(`ls`, `grep xyz`))
run(pipeline(`ls`, "out.txt"))
run(pipeline("out.txt", `grep xyz`))
# '基。流水线'-Method
pipeline(command; stdin, stdout, stderr, append=false)
将I/O重定向到或从指定的"命令"。 命名参数定义应重定向的命令流。 "Append"参数确定是否将输出数据添加到文件中。 这是具有两个参数的`pipeline`函数的更通用版本。 调用’pipeline(from,to)相当于当`from`是命令时调用`pipeline(from,stdout=to)
,或者当`from`是不同类型的数据源时调用`pipeline(to,stdin=from)`。
例子:
run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
run(pipeline(`update`, stdout="log.txt", append=true))
# '基。Libc。getpid`-Function
getpid() -> Int32
返回Julia进程的ID。
getpid(process) -> Int32
返回子进程的ID,如果它仍然存在。
兼容性:Julia1.1
此功能需要至少1.1的Julia版本。 |
# '基。@time'-Macro
@time expr
@time "description" expr
执行表达式并输出执行所花费的时间、内存中分配的对象数以及执行期间分配的总字节数的宏,之后返回表达式的值。 花在垃圾回收、编译新代码或重新编译无效代码上的时间以百分比显示。 还会显示延迟执行的锁冲突数。 '重入锁'。
如有必要,您可以指定将在所用时间报告之前显示的描述行。
系统可以检查表达式'@time’的内容,并在开始执行顶级表达式之前编译被调用的代码。 在这种情况下,花费在编译上的部分时间没有被考虑在内。 要考虑这个时间,你可以运行`@time@eval。..`.
另请参阅说明 '@showtime`, '@timev', '@定时', '@经过`, '@allocated'和 '@allocations'。
为了更全面的性能测试,您可以使用基准工具包中的宏"@btime"。jl,其中除其他外,多次评估函数以减少随机因素的影响。 |
兼容性:Julia1.8
添加描述的能力出现在版本Julia1.8中。 |
自Julia1.8以来,重新编译时间与编译时间分开显示。
兼容性:Julia1.11
Julia1.11中出现了阻止冲突的通知。 |
julia> x = rand(10,10);
julia> @time x * x;
0.606588 seconds (2.19 M allocations: 116.555 MiB, 3.75% gc time, 99.94% compilation time)
julia> @time x * x;
0.000009 seconds (1 allocation: 896 bytes)
julia> @time begin
sleep(0.3)
1+1
end
0.301395 seconds (8 allocations: 336 bytes)
2
julia> @time "A one second sleep" sleep(1)
A one second sleep: 1.005750 seconds (5 allocations: 144 bytes)
julia> for loop in 1:3
@time loop sleep(1)
end
1: 1.006760 seconds (5 allocations: 144 bytes)
2: 1.001263 seconds (5 allocations: 144 bytes)
3: 1.003676 seconds (5 allocations: 144 bytes)
# '基。@timev`-Macro
@timev expr
@timev "description" expr
这是宏`@time’的详细版本。 首先,它输出与`@time`相同的信息,然后是所有非零内存分配计数器,然后返回表达式的值。
如有必要,您可以指定将在花费的时间报告之前显示的描述字符串。
兼容性:Julia1.8
添加描述的能力出现在版本Julia1.8中。 |
另请参阅说明 '@时间', '@定时', '@经过`, '@allocated'和 '@分配'。
julia> x = rand(10,10);
julia> @timev x * x;
0.546770 seconds (2.20 M allocations: 116.632 MiB, 4.23% gc time, 99.94% compilation time)
elapsed time (ns): 546769547
gc time (ns): 23115606
bytes allocated: 122297811
pool allocs: 2197930
non-pool GC allocs:1327
malloc() calls: 36
realloc() calls: 5
GC pauses: 3
julia> @timev x * x;
0.000010 seconds (1 allocation: 896 bytes)
elapsed time (ns): 9848
bytes allocated: 896
pool allocs: 1
# '基。@timed'—Macro
@timed
执行表达式并返回其值的宏、以秒为单位的经过时间、以字节为单位的分配内存总量、垃圾回收的持续时间、具有不同内存分配计数器的对象、以秒为单位的编译时间和以秒为单位的重新编译时间。 还会显示延迟执行的锁冲突数。 '重入锁'。
系统可以检查'@timed’表达式的内容,并在开始执行顶级表达式之前编译被调用的代码。 在这种情况下,花费在编译上的部分时间没有被考虑在内。 要考虑这段时间,您可以运行`@timed@eval。..`.
另请参阅说明 '@时间', '@timev', '@经过`, '@分配', '@allocations'和 '@lock_conflicts'。
julia> stats = @timed rand(10^6);
julia> stats.time
0.006634834
julia> stats.bytes
8000256
julia> stats.gctime
0.0055765
julia> propertynames(stats.gcstats)
(:allocd, :malloc, :realloc, :poolalloc, :bigalloc, :freecall, :total_time, :pause, :full_sweep)
julia> stats.gcstats.total_time
5576500
julia> stats.compile_time
0.0
julia> stats.recompile_time
0.0
兼容性:Julia1.5
在Julia1.5中,此宏返回的值类型已从`Tuple’更改为’NamedTuple`。 |
兼容性:Julia1.11
在Julia1.11中添加了字段`lock_conflicts','compile_time’和’recompile_time'。 |
# '基。@经过`-Macro</no-翻译>
@elapsed
计算表达式的宏,而是将执行所花费的秒数作为浮点数返回。
系统可以检查'@elassed’表达式的内容,并在开始执行顶级表达式之前编译被调用的代码。 在这种情况下,花费在编译上的部分时间没有被考虑在内。 要考虑这段时间,您可以运行`@elased@eval。..`.
另请参阅说明 '@时间', '@timev', '@定时', '@allocated'和 '@allocations'。
julia> @elapsed sleep(0.3)
0.301391426
# '基。@lock_conflicts'-Macro
@lock_conflicts
计算表达式的宏,但不是结果返回计算期间的锁冲突总数,即进行锁尝试的情况 'ReentrantLock'导致等待,因为锁已经被设置。
julia> @lock_conflicts begin
l = ReentrantLock()
Threads.@threads for i in 1:Threads.nthreads()
lock(l) do
sleep(1)
end
end
end
5
兼容性:Julia1.11
此宏是在Julia1.11版本中添加的。 |
# '基。ENV'-Constant</no-翻译>
ENV
具有单个实例的对EnvDict类型的引用,该实例以字典的形式提供用于访问系统环境变量的接口。
(在Windows上,系统环境变量不区分大小写,因此’ENV`将所有键转换为大写以用于显示,迭代和复制。 在可移植代码中,变量不应该在大小写时有所不同;请记住,尽管用小写字母编写变量名称,但`ENV`中的相应键可能会用大写编写。)
更改环境不是线程安全的操作。 |
例子
julia> ENV
Base.EnvDict with "50" entries:
"SECURITYSESSIONID" => "123"
"USER" => "username"
"MallocNanoZone" => "0"
⋮ => ⋮
julia> ENV["JULIA_EDITOR"] = "vim"
"vim"
julia> ENV["JULIA_EDITOR"]
"vim"
# '基。系统。windows_version'-Function
Sys.windows_version()
将Windows NT内核版本号返回为"VersionNumber"类型的值,即"v"major。未成年人。build"'或者,如果功能不在Windows上运行,则’v"0.0.0"'。
# '基。系统。total_memory'-Function
Sys.total_memory()
返回以字节为单位的RAM总量(包括当前占用的RAM)。 例如,此卷可能仅限于Linux控制组。 要获得无限量,请使用"Sys"函数。total_physical_memory()'。
# '基。系统。free_physical_memory'-Function
Sys.free_physical_memory()
返回以字节为单位的可用系统内存量。 当前进程可能没有全部可用内存量;要获取实际可用内存量,请使用"Sys"函数。free_memory()'。
# '基。系统。total_physical_memory'-Function
Sys.total_physical_memory()
返回以字节为单位的RAM总量(包括当前占用的RAM)。 当前进程可能无法访问整个卷;请参阅函数’Sys的描述。total_memory()'。
# '基。系统。isjsvm'-Function
Sys.isjsvm([os])
用于检查Julia环境是否在JavaScript虚拟机(JSVM)上运行的谓词,包括例如在web浏览器中嵌入WebAssembly JavaScript。
兼容性:Julia1.2
此功能需要至少1.2的Julia版本。 |
# '基。系统。isexecutable'—Function
isexecutable(path::String)
如果指定的"路径"具有可执行文件权限,则返回"true"。
此权限可能会在用户执行`path’之前更改,因此建议执行文件并在失败的情况下处理错误,而不是首先调用’isexecutable'。 |
在Julia1.6之前,Windows文件系统ACL查询错误,因此对任何文件都返回值"true"。 从Julia1.6开始,该函数正确检测文件是否标记为可执行文件。 |
另请参阅说明 'ispath', "可读"及 'iswritable`。
# '基。系统。isreadable`-Function
isreadable(path::String)
如果根据此"path"对象的访问权限,当前用户可以从中读取,则返回值"true"。
此权限可能会在用户调用`open`之前更改,因此建议单独调用’open`并在失败的情况下处理错误,而不是首先调用`isreadable'。 |
目前,此函数不正确地轮询Windows文件系统ACL,因此它可能会返回不正确的结果。 |
兼容性:Julia1.11
此功能需要Julia至少1.11的版本。 |
另请参阅说明 'ispath`, 'isexecutable'和 'iswritable`。
isreadable(io) -> Bool
如果不支持从指定的I/O对象读取,则返回"false"。
例子
julia> open("myfile.txt", "w") do io
print(io, "Hello world!");
isreadable(io)
end
false
julia> open("myfile.txt", "r") do io
isreadable(io)
end
true
julia> rm("myfile.txt")
# '基。系统。iswritable`-Function
iswritable(path::String)
如果根据此"path"对象的访问权限,当前用户可以写入该对象,则返回值"true"。
此权限可能会在用户调用`open`之前更改,因此建议单独调用’open`并在失败的情况下处理错误,而不是首先调用`iswritable'。 |
目前,此函数不正确地轮询Windows文件系统ACL,因此它可能会返回不正确的结果。 |
兼容性:Julia1.11
此功能要求Julia的版本不低于1.11。 |
另请参阅说明 'ispath`, 'isexecutable'和 '可读`。
iswritable(io) -> Bool
如果不支持写入指定的I/O对象,则返回"false"。
例子
julia> open("myfile.txt", "w") do io
print(io, "Hello world!");
iswritable(io)
end
true
julia> open("myfile.txt", "r") do io
iswritable(io)
end
false
julia> rm("myfile.txt")
# '基。@静态'-Macro</no-翻译>
@static
在分析期间部分计算表达式。
例如,'@static Sys。iswindows()? foo:bar`评估函数`Sys。iswindows`)并在表达式中插入`foo`或’bar'。 这在构造在其他平台上无效的情况下很有用,例如在调用不存在的函数`ccall`时。 以下语法选项也是可以接受的’@static if Sys。isapple()foo end`和
@static foo<&&,||>bar'。
版本控制
# '基。版本号'-Type</no-翻译>
VersionNumber
规格对应的版本号类型https://semver.org /[语义版本控制(semver)]。 该值由主版本号和辅助版本号以及补丁号组成,后跟字母数字预发布和构建指定。
'VersionNumber’对象可以使用任何标准比较运算符进行比较。 (==
, <
, <=
依此类推)根据semver的规则。
"VersionNumber"具有以下公共字段:
-
'v.major::Integer`
-
'v.minor::Integer`
-
'v.补丁::整数`
-
'v.prerelease::元组{Vararg{Union{Integer, AbstractString}}}`
-
'v.构建::元组{Vararg{Union{Integer, AbstractString}}}`
另请参阅宏的描述 '@v_str',它允许您根据semver格式的文字字符串有效地创建`VersionNumber`对象,这是对常量的描述 'VERSION',包含使用的Julia版本的`VersionNumber’值,以及手册中专门用于 数字版本文字。
例子
julia> a = VersionNumber(1, 2, 3)
v"1.2.3"
julia> a >= v"1.2"
true
julia> b = VersionNumber("2.0.1-rc1")
v"2.0.1-rc1"
julia> b >= v"2.0.1"
false
错误
# '基。错误'-Function
error(message::AbstractString)
用指定的消息引发`ErrorException`。
error(msg...)
使用"string(msg)"创建的消息引发"ErrorException"。..)+`.
# '基。rethrow'-Function
rethrow()
从`catch`块重新调用当前异常。 重新引发的异常将被传递,就好像它没有被捕获一样。
替代形式’rethrow(e)`允许您将另一个异常对象`e’与当前回溯相关联。 但是,这给出了错误发生时程序状态的错误概念,因此建议使用"throw(e)"引发新异常。 在Julia1.1及更高版本中,当使用’throw(e)`调用时,初始异常保存在堆栈上;请参阅函数描述 'current_exceptions'。 |
# '基。current_exceptions`-Function
current_exceptions(task::Task=current_task(); [backtrace::Bool=true])
返回当前正在处理的异常堆栈。 在嵌套catch块的情况下,可能存在几个当前异常。 抛出的最后一个异常将是堆栈上的最后一个异常。 堆栈作为对象`ExceptionStack’返回—命名元组的抽象向量`(exception,backtrace)`。 如果’backtrace’参数为false,则每对中的backtrace将为’nothing'。
当传递’task’参数时,显式返回任意任务的当前异常堆栈。 这对于检查由于未捕获异常而无法完成的任务非常有用。
兼容性:Julia1.7
在Julia1.1—1.6版本中,这个函数是实验性的,称为’catch_stack()'并返回元组的简单向量。 |
# '基。@assert'-Macro
@assert cond [text]
导致错误 'AssertionError',如果条件’cond’为’false'。 这是编写表示被认为是真的条件的语句的首选语法,但用户可以检查这些条件以进行调试。 如果未满足批准,则显示可选的"文本"消息。
断言可能在某些优化级别被禁用。 因此,它们应仅用于调试目的。 不要使用断言来验证真实性(如密码)或数组边界。 函数在代码中的正确行为不应该基于执行`cond`的副作用。 |
例子
julia> @assert iseven(3) "3 is an odd number!"
ERROR: AssertionError: 3 is an odd number!
julia>@assert isodd(3)"什么是数字?"
# '基。实验性的。register_error_hint'-Function
Experimental.register_error_hint(handler, exceptiontype)
注册提示函数’handler(io,exception)`,它可以为用户提供解决错误的可能方法。 'Handler’函数应该检查’exception’是否满足发出提示的条件,如果满足,则将输出发送给’io'。 在包中,函数’register_error_hint’必须从函数'__init__'调用。
对于某些类型的异常,处理程序函数必须接受其他参数。
-
'MethodError':指定’handler(io,exc::MethodError,argtypes,kwargs)`将参数分隔为位置参数和命名参数。
提示文本通常应以`\n’开头。
定义自定义异常类型时,'showerror’方法可以通过调用支持提示 '基地。实验性的。show_error_hints'。
例子
julia> module Hinter only_int(x::Int) = 1 any_number(x::Number) = 2 function __init__() Base.Experimental.register_error_hint(MethodError) do io, exc, argtypes, kwargs if exc.f == only_int # Цвет необязателен, просто демонстрируется такая возможность. print(io, "\nDid you mean to call ") printstyled(io, "`any_number`?", color=:cyan) end end end end
如果你现在叫’Hinter。only_int`对于非Int类型的对象(这将导致’MethodError’错误),将显示提示:
julia> Hinter.only_int(1.0) ERROR: MethodError: no method matching only_int(::Float64) The function `only_int` exists, but no method is defined for this combination of argument types. Did you mean to call `any_number`? Closest candidates are: ...
兼容性:Julia1.5
从Julia1.5开始,用户错误提示可用。 |
这是一个实验界面。 它可以更改或删除,恕不另行通知。 为了避免更改,建议将所有注册放在'if isdefined(Base)内。实验,:register_error_hint)。.. 结束'。 |
# '基。实验性的。show_error_hints'-Function
Experimental.show_error_hints(io, ex, args...)
从调用所有处理程序 '基地。实验性的。register_error_hint'对于特定类型的异常,'typeof(ex)'。 'Args’必须包含处理程序期望用于此类型的所有其他参数。
兼容性:Julia1.5
从Julia1.5开始,用户错误提示可用。 |
这是一个实验界面。 它可以更改或删除,恕不另行通知。 |
# ’核心。BoundsError'*-Type
BoundsError([a],[i])
当通过索引访问数组’a`时,试图通过索引`i’访问越界元素。
例子
julia> A = fill(1.0, 7);
julia> A[8]
ERROR: BoundsError: attempt to access 7-element Vector{Float64} at index [8]
julia> B = fill(1.0, (2,3));
julia> B[2, 4]
ERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [2, 4]
julia> B[9]
ERROR: BoundsError: attempt to access 2×3 Matrix{Float64} at index [9]
# '核心。DivideError'-Type
DivideError()
已经尝试在分母中执行零整数除法。
例子
julia> 2/0
Inf
julia> div(2, 0)
ERROR: DivideError: integer division error
Stacktrace:
[...]
# ’核心。DomainError'*-Type
DomainError(val)
DomainError(val, msg)
函数或构造函数的`val’参数超出了定义的范围。
例子
julia> sqrt(-1)
ERROR: DomainError with -1.0:
sqrt was called with a negative real argument but will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
[...]
# ’核心。ErrorException'*-Type
ErrorException(msg)
一种通用类型的错误。 '中的错误消息。msg’字段可包含澄清信息。
例子
julia> ex = ErrorException("I've done a bad thing");
julia> ex.msg
"I've done a bad thing"
# ’核心。InexactError'*-Type
InexactError(name::Symbol, T, val)
无法在`name`函数的方法中准确地将`val`的值转换为类型`T`。
例子
julia> convert(Float64, 1+2im)
ERROR: InexactError: Float64(1 + 2im)
Stacktrace:
[...]
# '核心。InterruptException'-Type
InterruptException()
由于来自终端的中断(CTRL+C),该过程已停止。
请注意,在没有'-i`参数(交互式会话)的Julia脚本中,默认情况下不会调用’InterruptException`异常。 挑战 '基地。exit_on_sigint(false)`在脚本中,它可以恢复REPL的行为。 Julia脚本也可以使用以下命令运行
julia -e "include(popfirst!(ARGS))" script.jl
这样在执行过程中中断CTRL+C会导致’InterruptException’异常。
# '基。ProcessFailedException'-Type
ProcessFailedException
表示进程的退出状态,表示出现问题。 执行命令或管道时,此异常指示返回非零退出代码(即触发的进程已失败)。
# '基。SystemError'-Type
SystemError(prefix::AbstractString, [errno::Int32])
系统调用以错误代码结束(在全局变量`errno`中)。
# '核心。TypeError'-Type
TypeError(func::Symbol, context::AbstractString, expected::Type, got)
类型批准失败或具有不正确参数类型的内置函数调用。
# '核心。UndefKeywordError'-Type
UndefKeywordError(var::Symbol)
函数调用中没有指定所需的命名参数"var"。
例子
julia> function my_func(;my_arg)
return my_arg + 1
end
my_func (generic function with 1 method)
julia> my_func()
ERROR: UndefKeywordError: keyword argument `my_arg` not assigned
Stacktrace:
[1] my_func() at ./REPL[1]:2
[2] top-level scope at REPL[2]:1
# ’核心。UndefRefError'*-Type
UndefRefError()
没有为指定对象定义元素或字段。
例子
julia> struct MyType
a::Vector{Int}
MyType() = new()
end
julia> A = MyType()
MyType(#undef)
julia> A.a
ERROR: UndefRefError: access to undefined reference
Stacktrace:
[...]
# ’核心。UndefVarError'*-Type
UndefVarError(var::Symbol, [scope])
在当前区域中未定义符号。
例子
julia> a
ERROR: UndefVarError: `a` not defined in `Main`
julia> a = 1;
julia> a
1
# '基。重试'-Function
retry(f; delays=ExponentialBackOff(), check=nothing) -> Function
返回调用函数`f`的匿名函数。 如果发生异常,则每次`check`返回值`true`时,在暂停后再次调用函数’f',暂停的持续时间在`delays`参数中以秒为单位指定。 `Delays`和`Exception`对象的当前状态应该传递给’check'。
兼容性:Julia1.2
在Julia1.2之前,这个函数有一个有限的签名’f::Function'。 |
例子
retry(f, delays=fill(5.0, 3))
retry(f, delays=rand(5:10, 2))
retry(f, delays=Base.ExponentialBackOff(n=3, first_delay=5, max_delay=1000))
retry(http_get, check=(s,e)->e.status == "503")(url)
retry(read, check=(s,e)->isa(e, IOError))(io, 128; all=false)
活动
# '基。计时器'-Method</no-翻译>
Timer(callback::Function, delay; interval = 0)
创建一个计时器,每次触发时,都会执行’callback’函数。
挂起的任务被激活,`callback`函数在延迟`delay`秒后首先被调用,然后以`interval`秒的间隔再次被调用。 如果’interval’参数为'0',则回调只执行一次。 "回调"函数用一个参数调用—计时器本身。 要停止计时器,请调用"关闭"函数。 如果计时器结束倒计时’callback’函数可以最后执行一次。
例子
在这种情况下,第一个数字在两秒暂停后显示,并且以下数字在稍有延迟的情况下显示。
julia> begin
i = 0
cb(timer) = (global i += 1; println(i))
t = Timer(cb, 2, interval=0.2)
wait(t)
sleep(0.5)
close(t)
end
1
2
3
# '基。计时器'-Type</no-翻译>
Timer(delay; interval = 0)
创建一个计时器,用于激活等待触发的任务(通过调用函数 `wait')。
待处理任务在初始延迟至少’延迟’秒后被激活,然后以至少`间隔`秒的间隔重复执行。 如果`interval’参数为'0',则计时器只触发一次。 当计时器关闭时(使用函数 `close'),挂起的任务被激活并出现错误。 要检查计时器是否仍处于活动状态,请使用该函数 'isopen'。
间隔可能由于延迟的累积而逐渐移位。 如果您希望事件发生在某些绝对时间点,请在前一个结束后创建一个新的计时器,计算与下一个时间点的差异。 |
需要退出点来更新Timer对象的状态。 例如,'isopen(t::Timer)`不能用于在超时时结束无限while循环。 |
# '基。Asyncondition'-Method
AsyncCondition(callback::Function)
创建调用指定的’callback`函数的异步条件。 'Callback’函数传递一个参数,即异步条件对象本身。
展览及展览
# '基。parentmodule'-Function
parentmodule(m::Module) -> Module
返回包含此模块的"模块"。 它自己的父模块是’Main'。
例子
julia> parentmodule(Main)
Main
julia> parentmodule(Base.Broadcast)
Base
parentmodule(t::DataType) -> Module
定义一个模块,该模块包含’DataType’类型的定义(可能封装在`unionAll’中)。
例子
julia> module Foo
struct Int end
end
Foo
julia> parentmodule(Int)
Core
julia> parentmodule(Foo.Int)
Foo
parentmodule(f::Function) -> Module
定义包含通用函数的(第一个)定义的模块。
parentmodule(f::Function, types) -> Module
定义包含通用函数`f`的第一个方法的模块,对应于`types`的指定类型。
parentmodule(m::Method) -> Module
返回在其中定义指定方法`m`的模块。
兼容性:Julia1.9
要将`Method`作为参数传递,需要至少1.9的Julia版本。 |
# '基。pathof'-Method
pathof(m::Module)
返回导入`m`模块的`m.jl`文件的路径,或者返回值`nothing`(如果没有从包中导入`m`模块)。
使用功能 `dirname'从路径和函数中获取目录名 'basename'获取文件名。
另请参阅说明 'pkgdir'。
# '基。pkgdir'-Method
pkgdir(m::Module[, paths::String...])
返回在其中声明模块`m`的包的根目录,或者如果模块`m`未在包中声明,则返回值`nothing`。 如有必要,您可以指定构成包根目录内路径的路径组件。
要获取实现当前模块的包的根目录,可以使用"pkgdir(@__MODULE__)"形式。
如果指定了扩展模块,则返回父包的根目录。
julia> pkgdir(Foo)
"/path/to/Foo.jl"
julia> pkgdir(Foo, "src", "file.jl")
"/path/to/Foo.jl/src/file.jl"
另请参阅说明 'pathof'。
兼容性:Julia1.7
要使用可选的"路径"参数,Julia的版本至少为1.7。 |
# '基。pkgversion'-Method
pkgversion(m::Module)
返回从中导入模块`m`的包的版本,或者如果模块`m`未从包中导入或从包中导入而在版本字段中没有值,则返回值`nothing`。
版本是从包的项目中读取的。包下载过程中的toml文件。
要获取导入模块的软件包的版本,可以使用"pkgversion(@__MODULE__)"形式。
兼容性:Julia1.9
此功能出现在版本Julia1.9中。 |
# '基。moduleroot'-Function
moduleroot(m::Module) -> Module
查找指定模块的根模块。 这是父模块’m’链中的第一个模块,它可以是注册的根模块或它自己的父模块。
# '基。@__FILE__`-Macro
@__FILE__ -> String
展开为包含宏调用的文件路径的字符串,或者在使用`julia-e<expr>`计算时展开为空字符串。 如果没有关于分析器源代码的信息,它返回值’nothing'。 另请参阅常数的描述 'PROGRAM_FILE'。
# '基。@__DIR__`-Macro
@__DIR__ -> String
一个宏,用于以字符串的形式获取当前目录的绝对路径。
在脚本中,返回包含宏调用`@__DIR__'的脚本的目录。 当从REPL运行或使用`julia-e<expr>'计算时,它返回当前工作目录。
例子
`@__DIR__+`和`pwd()`行为的差异可以通过在当前工作目录以外的目录中创建一个简单的脚本并执行这两个命令来说明。:
julia> cd("/home/JuliaUser") # рабочий каталог
julia> # создаем скрипт по пути /home/JuliaUser/Projects
open("/home/JuliaUser/Projects/test.jl","w") do io
print(io, """
println("@__DIR__ = ", @__DIR__)
println("pwd() = ", pwd())
""")
end
julia> # выводит каталог скрипта и текущий рабочий каталог
include("/home/JuliaUser/Projects/test.jl")
@__DIR__ = /home/JuliaUser/Projects
pwd() = /home/JuliaUser
# '基。fullname'-Function
fullname(m::Module)
以字符元组的形式返回模块的全名。 例如:
例子
julia> fullname(Base.Iterators)
(:Base, :Iterators)
julia>全名(主要)
(:主要,)
# '基。名称'-Function
names(x::Module; all::Bool = false, imported::Bool = false)
返回公共名称"模块"的向量,不包括过时的名称。 如果’all’参数为true,则列表还包括模块中定义的非公共名称,过时名称和编译器生成的名称。 如果"导入"参数为true,则还包括从其他模块显式导出的名称。 名称按排序顺序返回。
在’Main’模块中定义的名称是一种特殊情况:它们都被认为是公共的,因为来自`Main`的名称在Julia中没有明确标记为public。
从`sym∈names(SomeModule)`_not_后跟`isdefined(SomeModule,sym)'。 'names’返回标记为`public`或`export’的字符,即使它们没有在模块中定义。 |
另请参阅说明 '基地。isexported', '基地。公共`, '基地。@当地人, '@__模块__`。
# '基。ispublic'-Function
ispublic(m::Module, s::Symbol) -> Bool
确定该符号是否在模块中标记为public。
导出的符号被认为是公开可用的。
兼容性:Julia1.11
这个特性和可访问性的概念出现在Julia1.11中。 |
另请参阅说明 'isexported', '名字'
julia> module Mod
export foo
public bar
end
Mod
julia> Base.ispublic(Mod, :foo)
true
julia> Base.ispublic(Mod, :bar)
true
julia> Base.ispublic(Mod, :baz)
false
# '基。名称'-Method</no-翻译>
nameof(f::Function) -> Symbol
返回通用函数`Function`的名称作为字符。 对于匿名函数,此名称由编译器生成。 对于显式声明的子类型’Function’是函数类型的名称。
# '基。functionloc'—Method
functionloc(f::Function, types)
返回具有通用函数`Function`定义位置的元组`(filename,line)'。
# '基。@locals'-Macro
@locals()
创建一个字典,其中包含名称(以符号的形式)和从调用地点开始定义的所有局部变量的值。
兼容性:Julia1.1
此宏需要至少1.1的Julia版本。 |
例子
julia> let x = 1, y = 2
Base.@locals
end
Dict{Symbol, Any} with 2 entries:
:y => 2
:x => 1
julia> function f(x)
local y
show(Base.@locals); println()
for i = 1:1
show(Base.@locals); println()
end
y = 2
show(Base.@locals); println()
nothing
end;
julia> f(42)
Dict{Symbol, Any}(:x => 42)
Dict{Symbol, Any}(:i => 1, :x => 42)
Dict{Symbol, Any}(:y => 2, :x => 42)
# '核心。getglobal'-Function
getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])
从"模块"获取"名称"绑定的值。 如果需要,可以为此操作指定原子排序,否则默认情况下将使用单调排序。
虽然访问模块绑定使用 'getfield'仍然支持兼容性’getglobal’应该总是首选,因为’getglobal’允许您控制原子排序(`getfield`总是单调的),并且更好地指示用户和编译器的代码目的。
大多数用户不应该直接调用此函数。 在所有情况下,除了非常具体的情况外,您应该使用该函数 'getproperty'或适当的语法(即`module.name `)。
兼容性:Julia1.9
此功能需要至少1.9的Julia版本。 |
另请参阅说明 getproperty'
和 'setglobal!.
例子
julia> a = 1
1
julia> module M
a = 2
end;
julia> getglobal(@__MODULE__, :a)
1
julia> getglobal(M, :a)
2
#
'核心。setglobal!
*-Function</no-翻译>
setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])
将模块中绑定的名称(name')的值设置或更改为`x
。 不执行类型转换,因此如果类型已经被声明用于绑定,则`x’必须具有适当的类型,否则将发生错误。
此外,可以为此操作指定原子排序,否则默认情况下将使用单调排序。
用户通常使用该功能访问此功能 'setproperty!'或适当的语法(即`module.name =x`),因此它仅用于非常特定的用例。
兼容性:Julia1.9
此功能需要至少1.9的Julia版本。 |
另请参阅说明 'setproperty!`和 'getglobal'。
例子
julia> module M; global a; end;
julia> M.a # то же, что и `getglobal(M, :a)`
ERROR: UndefVarError: `a` not defined in `M`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.
Stacktrace:
[1] getproperty(x::Module, f::Symbol)
@ Base ./Base.jl:42
[2] top-level scope
@ none:1
julia> setglobal!(M, :a, 1)
1
julia> M.a
1
#
'核心。修改全球!
*-Function</no-翻译>
modifyglobal!(module::Module, name::Symbol, op, x, [order::Symbol=:monotonic]) -> Pair
在应用`op`函数后,原子地执行获取和设置全局变量的操作。
兼容性:Julia1.11
此功能要求Julia的版本不低于1.11。 |
另请参阅说明 'modifyproperty!和 'setglobal!.
#
'核心。swapglobal!
*-Function</no-翻译>
swapglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])
原子地执行用于同时获取和设置全局变量的操作。
兼容性:Julia1.11
此功能需要Julia至少1.11的版本。 |
另请参阅说明 'swapproperty!和 'setglobal!.
#
'核心。setglobalonce!
*-Function</no-翻译>
setglobalonce!(module::Module, name::Symbol, value,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool
原子地执行将指定值赋给全局变量(如果尚未设置)的操作。
兼容性:Julia1.11
此功能要求Julia的版本不低于1.11。 |
另请参阅说明 'setpropertyonce!和 'setglobal!.
#
'核心。替换掉!
*-Function</no-翻译>
replaceglobal!(module::Module, name::Symbol, expected, desired,
[success_order::Symbol, [fail_order::Symbol=success_order]) -> (; old, success::Bool)
原子地执行获取全局变量并有条件地将指定值赋给它的操作。
兼容性:Julia1.11
此功能要求Julia的版本不低于1.11。 |
另请参阅说明 'replaceproperty!和 'setglobal!.
文件
(有关更多信息,请参阅 文件。)
#
'核心。@doc
*-Macro
文件
函数、方法和类型可以通过在定义前添加一行来记录。:
""" # Функция Foo `foo(x)`: Делает Foo с `x`. """ foo(x) = ...
使用宏"@doc",您可以直接设置和接收文档和元数据。 宏以特殊的方式分析代码,以便在下一行中指定文档对象:
@doc "blah" function foo() ...
默认情况下,文档以Markdown格式编写,但任何对象都可以用作第一个参数。
将对象与其定义分开记录
您可以在定义之前或之后记录对象,如下所示:
@doc "foo" function_to_doc @doc "bar" TypeToDoc
对于宏,语法看起来像'@doc"macro doc":(Module。@macro)',而对于字符串宏--'@doc"macro doc":(string_macro"")。 没有引号
:(’的宏扩展被记录下来。
获取文件
您可以获取函数、宏和其他对象的文档,如下所示:
@doc foo @doc @time @doc md""
功能和方法
如果文档放在方法定义之前(例如,function foo()。..+'或'+foo()=。..
),它特指这种方法,而不是整个函数。 方法的文档按照定义的顺序组合在一起,形成函数的文档。
#
'基。文件。HTML'-Type
HTML(S)
:创建一个以HTML格式显示`S’的对象。
HTML("<div>foo</div>")
您还可以将流用于大量数据。:
HTML() do io println(io, "<div>foo</div>") end
'HTML’函数目前是为了向后兼容而导出的,但是这个导出已经过时了。 建议使用这种类型作为 'Docs.HTML'或从`Docs’显式导入它。 |
# '基。文件。hasdoc`-Function
Docs.hasdoc(mod::Module, sym::Symbol)::Bool
如果`mod`中的`sym`有docstring,则返回值’true',否则返回值`false`。
# '基。文件。unocumented_names'-Function
undocumented_names(mod::Module; private=false)
返回"模块"中未记录字符的排序向量(即没有docstring的字符)。 当设置为’private=false'(默认情况下)时,只返回声明为`public`和/或`export`的标识符,当设置为`private=true`时,返回模块中的所有符号(编译器生成并以`#`开头的隐藏符号除外)。
另请参阅说明 '名字', 'Docs.hasdoc', '基地。ispublic'。
上传代码
# '基。identify_package'-Function
Base.identify_package(name::String)::Union{PkgId, Nothing}
Base.identify_package(where::Union{Module,PkgId}, name::String)::Union{PkgId, Nothing}
从当前环境堆栈中按其名称标识包,如果找不到包,则返回其"PkgId"或"nothing"。
如果只指定了’name’参数,它会搜索堆栈中的每个环境及其命名的直接依赖项。
"Where"参数指定搜索包的上下文:在这种情况下,它首先检查名称是否与上下文本身匹配,否则它搜索所有递归依赖项(从每个环境的已解析清单),直到找到"where"上下文,然后识别具有适当名称的依赖项。
julia> Base.identify_package("Pkg") # Pkg является зависимостью среды по умолчанию
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]
julia> using LinearAlgebra
julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg не является зависимостью линейной алгебры
# '基。locate_package'-Function
Base.locate_package(pkg::PkgId)::Union{String, Nothing}
与标识符`pkg`相对应的包的入口点文件的路径,如果没有找到,则为`nothing`。 另请参阅说明 'identify_package'。
julia> pkg = Base.identify_package("Pkg")
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]
julia> Base.locate_package(pkg)
"/path/to/julia/stdlib/v1.11/Pkg/src/Pkg.jl"
# '基。需要'-Function
require(into::Module, module::Symbol)
在每个活动节点上的"主"模块的上下文中加载源代码文件,搜索标准文件位置。 'require’被认为是顶级操作,因此它将当前路径设置为’include`,但不使用它来搜索文件(请参阅功能帮助 '包括')。 此函数通常用于加载库代码,并由’using`命令隐式调用以加载包。
搜索文件时,'require’函数首先搜索全局数组中的包代码。 'LOAD_PATH'。 'require’在所有平台上都需要区分大小写的字符,包括那些不区分大小写的文件系统(如macOS和Windows)。
# '基。compilecache'-Function
Base.compilecache(module::PkgId)
为模块及其所有依赖项创建预编译缓存文件。 它减少了包装加载时间。 缓存文件存储在"DEPOT_PATH[1]/compiled"文件夹中。 在该部分 模块的初始化和预编译提供了重要说明。
# '基。isprecompiled'-Function
Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)
确定是否已在活动项目中预编译具有指定PkgId的包。
在当前未加载预期的依赖项版本的情况下,此检查期间默认使用与加载代码时相同的方法。 要忽略加载的模块并获得新Julia会话的结果,请指定’ignore_loaded=true'。
兼容性:Julia1.10
此功能需要Julia至少1.10的版本。 |
# '基。get_extension'-Function
get_extension(parent::Module, extension::Symbol)
返回"父"的"扩展"模块,或者如果未加载扩展,则返回"无"模块。
内部组件
# '基。GC。gc'-Function
GC.gc([full=true])
执行垃圾回收。 "Full"参数定义了程序集的类型:当完全组装时(默认情况下),所有活动对象都被绕过(完全标记),内存被清除所有不可访问的对象。 对于增量构建,只有不可用的所谓"年轻"对象才会从内存中清除。
垃圾回收器可能决定执行完整构建,即使已请求增量构建也是如此。
经常使用它可能会导致性能下降。 |
# '基。GC。启用'-Function
GC.enable(on::Bool)
使用逻辑参数启用或禁用垃圾回收(启用"true",禁用"false")。 返回以前的垃圾回收状态。
您应该小心禁用垃圾回收,因为这可能会导致内存消耗无限增加。 |
# '基。GC。@preserve'-Macro
GC.@preserve x1 x2 ... xn expr
标记对象的+x1,x2,…在表达式`expr`的评估过程中使用了+'。 仅当表达式`expr`_显式uses_内存或属于一个或多个对象`x’的其他资源时,在不安全代码中才需要它。
对象"x"的隐式使用是对编译器不可见的逻辑上属于"x"的资源的任何间接使用。 一些例子:
-
通过"Ptr"直接访问对象的内存;
-
在调用`ccall`中传递指向对象`x`的指针;
-
使用终结器将释放的对象`x`的资源。
在标准情况下,`@preserve’宏通常对性能没有影响,因为对象的生存期略有增加。 "@Preserve"宏的实现可能会产生诸如保护动态分配的对象免受垃圾回收等后果。
例子
当使用`unsafe_load’通过指针加载时,基对象被隐式使用。 例如,对象’x`由函数`unsafe load(p)`在以下代码中隐式使用:
julia> let
x = Ref{Int}(101)
p = Base.unsafe_convert(Ptr{Int}, x)
GC.@preserve x unsafe_load(p)
end
101
将指针传递到ccall时,指针引用的对象隐式使用,必须保留。 (但是,请记住,通常对象’x`直接传递给`ccall',这被认为是显式用法。)
julia> let
x = "Hello"
p = pointer(x)
Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)
# Предпочтительная альтернатива
Int(@ccall strlen(x::Cstring)::Csize_t)
end
5
# '基。GC。safepoint'-Function
GC.safepoint()
向可以执行垃圾回收的程序添加一个点。 在多线程程序中,一些线程为对象分配内存(因此可能需要垃圾回收),而另一些线程只执行简单操作(不分配内存、切换任务或I/O),这种情况非常有用。 在不分配内存的线程上定期调用此函数允许垃圾回收。
兼容性:Julia1.4
此功能首先在Julia1.4中实现。 |
# '基。元。解析'-Method
parse(str, start; greedy=true, raise=true, depwarn=true, filename="none")
分析包含表达式的字符串并返回表达式(然后可以将其传递给eval函数以执行)。 'start’是与字符串`str`中的第一个字符对应的代码单元的索引,分析应该从该索引开始(按索引访问字符串时通常如此,这不是字符的索引)。 如果’greedy’参数设置为’true'(默认情况下),`parse’函数将尝试处理尽可能多的数据。 否则,一旦分析了有效表达式,处理就会停止。 对于不完整但在语法上有效的表达式,返回`Expr(:incomplete,"(error message)")'。 如果’raise’参数设置为’true'(默认情况下),则在检测到语法错误时会发生错误(不包括不完整的表达式)。 如果’raise’参数设置为’false',则’parse’函数返回将生成错误的表达式。 如果’depwarn’参数设置为’false',则不会发出有关停用的警告。 'Filename’参数用于在发生错误时输出诊断信息。
julia> Meta.parse("(α, β) = 3, 5", 1) # начало строки
(:((α, β) = (3, 5)), 16)
julia> Meta.parse("(α, β) = 3, 5", 1, greedy=false)
(:((α, β)), 9)
julia> Meta.parse("(α, β) = 3, 5", 16) # конец строки
(nothing, 16)
julia> Meta.parse("(α, β) = 3, 5", 11) # индекс 3
(:((3, 5)), 16)
julia> Meta.parse("(α, β) = 3, 5", 11, greedy=false)
(3, 13)
# '基。元。解析'-Method</no-翻译>
parse(str; raise=true, depwarn=true, filename="none")
尽可能多地分析包含表达式的字符串,并返回单个表达式。 如果第一个表达式后面有更多字符,则会发生错误。 如果’raise’参数设置为’true'(默认情况下),则在检测到语法错误时发生错误;否则,`parse`函数返回将导致错误的表达式。 如果’depwarn’参数设置为’false',则不会发出有关停用的警告。 'Filename’参数用于在发生错误时输出诊断信息。
julia> Meta.parse("x = 3")
:(x = 3)
julia> Meta.parse("1.0.2")
ERROR: ParseError:
# Error @ none:1:1
1.0.2
└──┘ ── invalid numeric constant
[...]
julia> Meta.parse("1.0.2"; raise = false)
:($(Expr(:error, "invalid numeric constant "1.0."")))
julia> Meta.parse("x = ")
:($(Expr(:incomplete, "incomplete: premature end of input")))
# '基。macroexpand'-Function
macroexpand(m::Module, x; recursive=true)
接受表达式’x`并返回一个等效表达式,其中所有宏都已被删除(展开)以在模块’m’中执行。 命名的"递归"参数确定是否展开更深层次的嵌套宏。 下面的示例演示了这一点:
julia> module M
macro m1()
42
end
macro m2()
:(@m1())
end
end
M
julia> macroexpand(M, :(@m2()), recursive=true)
42
julia> macroexpand(M, :(@m2()), recursive=false)
:(#= REPL[16]:6 =# M.@m1)
# '基。@macroexpand'-Macro
@macroexpand [mod,] ex
返回一个等效表达式,其中所有宏都已被删除(展开)。 如果指定了两个参数,则第一个参数包含要在其中执行计算的模块。
在宏'@macroexpand’和函数之间 'macroexpand'存在差异。
-
功能 'macroexpand'接受命名参数’recursive`,宏`@macroexpand’总是递归地工作。 此宏没有递归的版本 — '@macroexpand1'。
-
的功能 'macroexpand'有一个显式指定的’module’参数,宏'@macroexpand’总是执行相对于调用它的模块的扩展。
这在下面的例子中清楚地看到。
julia> module M
macro m()
1
end
function f()
(@macroexpand(@m),
macroexpand(M, :(@m)),
macroexpand(Main, :(@m))
)
end
end
M
julia> macro m()
2
end
@m (macro with 1 method)
julia> M.f()
(1, 1, 2)
当使用'@macroexpand`时,表达式在代码中使用宏`@macroexpand`的地方展开(在示例中,这是`M`模块)。 当使用’macroexpand’时,表达式在第一个参数中指定的模块中展开。
兼容性:Julia1.11
具有两个参数的表单需要至少1.11的Julia版本。 |
# '基。code_lowered'-Function
code_lowered(f, types; generated=true, debuginfo=:default)
返回与指定的通用函数和类型签名对应的方法的缩减形式(中间表示)数组。
如果’generated’参数为’false`,则返回的’CodeInfo’实例对应于标准实现。 如果没有标准实现,则会发生错误。 如果’generated’参数为’true`,则这些`CodeInfo’实例对应于扩展生成器所产生的方法体。
命名参数’debuginfo’定义输出中的代码元数据量。
请注意:如果`types’中的类型不是最终的,当`generated`参数为’true`并且任何相应的方法标记为`@generated’时,会发生错误。
# '基。code_typed'-Function
code_typed(f, types; kw...)
返回与指定的通用函数和类型签名对应的方法的类型输出的缩减形式(中间表示)数组。
命名参数
-
'optimize::Bool=true`:可选,确定是否应用了其他优化,例如嵌入。
-
'debuginfo::Symbol=:default':可选,定义输出数据中的代码元数据量。 可能的值’:source’和':none'。
内部命名参数
本节仅适用于那些了解Julia编译器内部原理的人。
-
'world::UInt=Base。get_world_counter`)':可选,定义搜索方法时使用的"世界年龄"。 如果省略此论点,则使用当前的"世界年龄"。
-
'interp::核心。编译器。AbstractInterpreter=核心。编译器。NativeInterpreter`world)':可选,定义使用的抽象解释器。 如果未指定此参数,则使用自定义解释器。
例子
参数的类型可以指定为元组,以获得’code_typed’函数的相应结果。
julia> code_typed(+, (Float64, Float64))
1-element Vector{Any}:
CodeInfo(
1 ─ %1 = Base.add_float(x, y)::Float64
└── return %1
) => Float64
# '基。预编译`-Function
precompile(f, argtypes::Tuple{Vararg{Any}})
编译指定的函数’f`,考虑到作为元组传递给`argtypes’的参数类型,但不执行它。
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)
为指定的参数类型执行特定方法的预编译。 您可以使用与通常在分派期间选择的方法不同的预编译方法,从而模拟`invoke'。
元功能
# '基。isexpr'-Function
Meta.isexpr(ex, head[, n])::Bool
如果`ex`是指定的`head`类型的`Expr`对象,则返回值`true'。 您还可以检查其参数的数量是否等于值’n'。 'Head’参数可以包含’Symbol’类型的对象或`Symbol`对象的集合。 例如,要检查函数调用表达式是否已传递给宏,可以使用’isexpr(ex,:call)`。
例子
julia> ex = :(f(x))
:(f(x))
julia> Meta.isexpr(ex, :block)
false
julia> Meta.isexpr(ex, :call)
true
julia> Meta.isexpr(ex, [:block, :call]) # несколько возможных заголовков
true
julia> Meta.isexpr(ex, :call, 1)
false
julia> Meta.isexpr(ex, :call, 2)
true
# '基。isidentifier'-Function
isidentifier(s) -> Bool
确定字符或字符串’s’是否包含在Julia代码中作为正常有效名称(而不是二进制或一元运算符)解析的字符。 另请参阅说明 '基地。isoperator'。
Julia’Symbol’对象中允许使用任何字符序列(除了`\0'),因此宏会自动使用带有`#`符号的变量名称,以避免与周围代码的名称冲突。 为了使分析器能够识别变量,使用了一组有限的字符(由于Unicode而显着扩展)。 `Isidentifier()'函数允许您直接从分析器请求Symbol对象是否包含有效字符。
例子
julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
(true, false)
# '基。isoperator'-Function
isoperator(s::Symbol)
如果字符可以用作运算符,则返回值`true`;否则,它返回’false'。
例子
julia> Meta.isoperator(:+), Meta.isoperator(:f)
(true, false)
# '基。isunaryoperator'-Function
isunaryoperator(s::Symbol)
如果字符可以用作一元(前缀)运算符,则返回值`true`;否则,它返回’false'。
例子
julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
(true, true, false)
# '基。isbinaryoperator'-Function
isbinaryoperator(s::Symbol)
如果字符可以用作二进制(中缀)运算符,则返回值`true`;否则,它返回’false'。
例子
julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
(true, false, false)
# '基。元。show_sexpr'-Function
Meta.show_sexpr([io::IO,], ex)
输出’ex’图像作为Lisp风格的s表达式。
例子
julia> Meta.show_sexpr(:(f(x, g(y,z))))
(:call, :f, :x, (:call, :g, :y, :z))