基本概念

简介

Julia Base 包含一系列适合进行科学和数值计算的函数和宏,但也与许多通用编程语言一样广泛。更多功能可从不断增长的 可用包 集合中获得。下面按主题对函数进行分组。

一些一般性说明

  • 要使用模块函数,请使用 import Module 导入模块,并使用 Module.fn(x) 使用函数。
  • 或者,using Module 会将所有导出的 Module 函数导入到当前命名空间中。
  • 按照惯例,以感叹号 (!) 结尾的函数名会修改它们的参数。某些函数同时拥有修改 (例如,sort!) 和非修改 (sort) 版本。

Base 和标准库的行为仅在 SemVer 中定义为稳定,如果它们已记录;即,包含在 Julia 文档 中,并且未被标记为不稳定。有关更多信息,请参见 API 常见问题解答

使用指南

Base.exit函数
exit(code=0)

使用退出代码停止程序。默认退出代码为零,表示程序已成功完成。在交互式会话中,可以使用键盘快捷键 ^D 调用 exit()

来源
Base.atexit函数
atexit(f)

注册一个零参数或一个参数的函数 f(),以便在进程退出时调用。atexit() 钩子以后进先出 (LIFO) 的顺序调用,并在对象终结器之前运行。

如果 f 为一个整数参数定义了一个方法,则它将作为 f(n::Int32) 调用,其中 n 是当前退出代码,否则它将作为 f() 调用。

Julia 1.9

一个参数形式要求 Julia 1.9

退出钩子允许调用 exit(n),在这种情况下,Julia 将使用退出代码 n 退出(而不是原始退出代码)。如果多个退出钩子调用 exit(n),则 Julia 将使用对应于最后调用的 exit(n) 退出钩子的退出代码。(因为退出钩子以 LIFO 顺序调用,“最后调用”等效于“最先注册”。)

注意:一旦所有退出钩子都被调用,就不允许再注册退出钩子,并且在所有钩子都完成之后对 atexit(f) 的任何调用都会抛出异常。这种情况可能发生在从在关闭期间可能仍在并发执行的后台任务中注册退出钩子时。

来源
Base.summarysize函数
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
来源
Base.__precompile__函数
__precompile__(isprecompilable::Bool)

指定调用此函数的文件是否可预编译,默认为 true。如果一个模块或文件不能安全地预编译,则它应该调用 __precompile__(false),以便在 Julia 尝试预编译它时抛出错误。

来源
Base.include函数
Base.include([mapexpr::Function,] m::Module, path::AbstractString)

在模块 m 的全局范围内评估输入源文件的内容。每个模块(除使用 baremodule 定义的模块外)都拥有自己的 include 定义,它省略了 m 参数,该参数在该模块中评估文件。返回输入文件的最后一个已评估表达式的结果。在包含期间,一个任务本地包含路径被设置为包含该文件的目录。对 include 的嵌套调用将在该路径的相对位置进行搜索。此函数通常用于交互式加载源代码,或者将拆分为多个源文件的包中的文件组合起来。

可选的第一个参数 mapexpr 可用于在评估包含的代码之前对其进行转换:对于 path 中的每个解析表达式 exprinclude 函数实际上会评估 mapexpr(expr)。如果省略,mapexpr 默认为 identity

Julia 1.5

传递 mapexpr 参数需要 Julia 1.5。

来源
Base.MainInclude.include函数
include([mapexpr::Function,] path::AbstractString)

在包含模块的全局范围内评估输入源文件的内容。每个模块(除使用 baremodule 定义的模块外)都拥有自己的 include 定义,该参数在该模块中评估文件。返回输入文件的最后一个已评估表达式的结果。在包含期间,一个任务本地包含路径被设置为包含该文件的目录。对 include 的嵌套调用将在该路径的相对位置进行搜索。此函数通常用于交互式加载源代码,或者将拆分为多个源文件的包中的文件组合起来。参数 path 使用 normpath 进行规范化,这将解析诸如 .. 之类的相对路径标记并将 / 转换为适当的路径分隔符。

可选的第一个参数 mapexpr 可用于在评估包含的代码之前对其进行转换:对于 path 中的每个解析表达式 exprinclude 函数实际上会评估 mapexpr(expr)。如果省略,mapexpr 默认为 identity

使用 Base.include 将文件评估到另一个模块中。

Julia 1.5

传递 mapexpr 参数需要 Julia 1.5。

来源
Base.include_string函数
include_string([mapexpr::Function,] m::Module, code::AbstractString, filename::AbstractString="string")

include 类似,但从给定的字符串而不是从文件读取代码。

可选的第一个参数 mapexpr 可用于在评估包含的代码之前对其进行转换:对于 code 中的每个解析表达式 exprinclude_string 函数实际上会评估 mapexpr(expr)。如果省略,mapexpr 默认为 identity

Julia 1.5

传递 mapexpr 参数需要 Julia 1.5。

来源
Base.include_dependency函数
include_dependency(path::AbstractString)

在一个模块中,声明由path指定的文件、目录或符号链接(相对或绝对)是预编译的依赖项;也就是说,如果path的修改时间改变,则需要重新编译模块。

这只有在您的模块依赖于未通过include使用的路径时才需要。它在编译之外没有影响。

来源
__init__关键字
__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
来源
Base.which方法
which(f, types)

返回f(一个Method对象)的方法,该方法将针对给定types的参数调用。

如果types是抽象类型,则返回invoke将调用的方法。

另请参阅:parentmodule,以及InteractiveUtils中的@which@edit

来源
Base.methods函数
methods(f, [types], [module])

返回f的方法表。

如果指定了types,则返回一个类型匹配的方法数组。如果指定了module,则返回在该模块中定义的方法数组。也可以将模块列表指定为数组。

Julia 1.4

至少需要 Julia 1.4才能指定模块。

另请参阅:which@which

来源
Base.@show
@show exs...

将一个或多个表达式及其结果打印到stdout,并返回最后一个结果。

另请参阅:show@infoprintln

示例

julia> x = @show 1+2
1 + 2 = 3
3

julia> @show x^2 x/2;
x ^ 2 = 9
x / 2 = 1.5
来源
Base.MainInclude.err常量
err

一个变量,引用最后一个抛出的错误,自动导入到交互式提示符中。抛出的错误收集在一个异常堆栈中。

来源

关键字

这是 Julia 中的保留关键字列表:baremodulebeginbreakcatchconstcontinuedoelseelseifendexportfalsefinallyforfunctionglobalifimportletlocalmacromodulequotereturnstructtruetryusingwhile。这些关键字不允许用作变量名。

以下两个词序列是保留的:abstract typemutable structprimitive type。但是,您可以创建具有以下名称的变量:abstractmutableprimitivetype

最后:where被解析为一个中缀运算符,用于编写参数化方法和类型定义;inisa被解析为中缀运算符;outer在用于修改for循环的迭代规范中变量的作用域时被解析为一个关键字;as用作一个关键字,用于重命名由importusing引入作用域的标识符。但是,允许创建名为whereinisaouteras的变量。

module关键字
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
来源
export关键字
export

export在模块中使用,用于告诉 Julia 哪些函数应该提供给用户。例如:export foo使名称foousing模块时可用。有关详细信息,请参阅关于模块的手册部分

来源
import关键字
import

import Foo将加载模块或包Foo。来自导入的Foo模块的名称可以使用点语法访问(例如,Foo.foo访问名称foo)。有关详细信息,请参阅关于模块的手册部分

来源
using关键字
using

using Foo将加载模块或包Foo,并使其exported名称可供直接使用。名称也可以使用点语法访问(例如,Foo.foo访问名称foo),无论它们是否被exported。有关详细信息,请参阅关于模块的手册部分

来源
as关键字
as

as用作一个关键字,用于重命名由importusing引入作用域的标识符,用于解决名称冲突以及缩短名称。(在importusing语句之外,as不是关键字,可以用作普通标识符。)

import LinearAlgebra as LA将导入的LinearAlgebra标准库引入作用域,作为LA

import LinearAlgebra: eigen as eig, cholesky as cholLinearAlgebra中的eigencholesky方法引入作用域,分别作为eigchol

as仅在将单个标识符引入作用域时才与using一起使用。例如,using LinearAlgebra: eigen as eigusing LinearAlgebra: eigen as eig, cholesky as chol有效,但using LinearAlgebra as LA是无效语法,因为它没有意义将LinearAlgebra所有导出的名称重命名为LA

来源
baremodule关键字
baremodule

baremodule声明一个不包含using Baseevalinclude的本地定义的模块。它仍然会导入Core。换句话说,

module Mod

...

end

等价于

baremodule Mod

using Base

eval(x) = Core.eval(Mod, x)
include(p) = Base.include(Mod, p)

...

end
来源
function关键字
function

使用function关键字定义函数

function add(a, b)
    return a + b
end

或简短形式表示法

add(a, b) = a + b

return关键字的使用与其他语言完全相同,但通常是可选的。没有显式return语句的函数将返回函数体中的最后一个表达式。

来源
macro关键字
macro

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
来源
return关键字
return

return x导致封闭函数提前退出,将给定值x传递回其调用方。return本身没有值等价于return nothing(见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关键字
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关键字
begin

begin...end表示一段代码块。

begin
    println("Hello, ")
    println("World!")
end

通常begin是不必要的,因为functionlet之类的关键字会隐式地开始代码块。另请参阅;

begin还可以在索引时使用,表示集合的第一个索引或数组维度的第一个索引。

示例

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
来源
end关键字
end

end 标记一个表达式块的结束,例如 modulestructmutable structbeginletfor 等。

end 也可用于索引,表示集合的最后一个索引或数组维度中的最后一个索引。

示例

julia> A = [1 2; 3 4]
2×2 Array{Int64, 2}:
 1  2
 3  4

julia> A[end, :]
2-element Array{Int64, 1}:
 3
 4
来源
let关键字
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,这些 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关键字
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,如果为真,则评估相应的代码块;如果两个表达式都不为真,则评估 else 代码块。elseifelse 代码块是可选的,可以使用任意数量的 elseif 代码块。

与其他一些语言不同,条件必须是 Bool 类型。条件不能仅转换为 Bool

julia> if 1 end
ERROR: TypeError: non-boolean (Int64) used in boolean context
来源
for关键字
for

for 循环在迭代值序列时重复评估语句块。

迭代变量始终是一个新的变量,即使在封闭作用域中存在相同名称的变量。使用 outer 重用现有局部变量进行迭代。

示例

julia> for i in [1, 4, 0]
           println(i)
       end
1
4
0
来源
while关键字
while

while 循环重复评估条件表达式,只要表达式保持为真,就继续评估 while 循环的主体。如果条件表达式在第一次到达 while 循环时为假,则主体永远不会被评估。

示例

julia> i = 1
1

julia> while i < 5
           println(i)
           global i += 1
       end
1
2
3
4
来源
break关键字
break

立即退出循环。

示例

julia> i = 0
0

julia> while true
           global i += 1
           i > 5 && break
           println(i)
       end
1
2
3
4
5
来源
continue关键字
continue

跳过当前循环迭代的剩余部分。

示例

julia> for i = 1:6
           iseven(i) && continue
           println(i)
       end
1
3
5
来源
try关键字
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 结构的强大之处在于能够立即将深度嵌套的计算解开到调用函数堆栈中的更高级别。

来源
finally关键字
finally

在给定代码块退出时运行一些代码,无论它如何退出。例如,以下是我们如何确保打开的文件已关闭的方法。

f = open("file")
try
    operate_on_file(f)
finally
    close(f)
end

当控制离开 try 代码块(例如,由于 return 或只是正常完成)时,close(f) 将被执行。如果 try 代码块由于异常而退出,则异常将继续传播。catch 代码块也可以与 tryfinally 组合使用。在这种情况下,finally 代码块将在 catch 处理错误后运行。

来源
quote关键字
quote

quote 在块中创建多个表达式对象,而无需使用显式的 Expr 构造函数。例如。

ex = quote
    x = 1
    y = 2
    x + y
end

与其他引用方式 :( ... ) 不同,此形式在表达式树中引入了 QuoteNode 元素,在直接操作树时必须考虑这些元素。对于其他目的,:( ... )quote .. end 代码块将被视为相同。

来源
local关键字
local

local 引入新的局部变量。有关更多信息,请参阅 变量作用域手册部分

示例

julia> function foo(n)
           x = 0
           for i = 1:n
               local x # introduce a loop-local x
               x = i
           end
           x
       end
foo (generic function with 1 method)

julia> foo(10)
0
来源
global关键字
global

global x 使当前作用域及其内部作用域中的 x 引用具有该名称的全局变量。有关更多信息,请参阅 变量作用域手册部分

示例

julia> z = 3
3

julia> function foo()
           global z = 6 # use the z variable defined outside foo
       end
foo (generic function with 1 method)

julia> foo()
6

julia> z
6
来源
outer关键字
for outer

for 循环中重用现有局部变量进行迭代。

有关更多信息,请参阅 变量作用域手册部分

另请参阅 for

示例

julia> function f()
           i = 0
           for i = 1:3
               # empty
           end
           return i
       end;

julia> f()
0
julia> function f()
           i = 0
           for outer i = 1:3
               # empty
           end
           return i
       end;

julia> f()
3
julia> i = 0 # global variable
       for outer i = 1:3
       end
ERROR: syntax: no outer local variable declaration exists for "for outer"
[...]
来源
const关键字
const

const 用于声明值不会改变的全局变量。在几乎所有代码(尤其是性能敏感的代码)中,都应以这种方式声明全局变量为常量。

const x = 5

可以在单个 const 中声明多个变量。

const y, z = 7, 11

请注意,const 仅适用于一个 = 操作,因此 const x = y = 1 声明 x 为常量,但 y 不是。另一方面,const x = const y = 1 声明 xy 都是常量。

请注意,“常量”不会扩展到可变容器;只有变量与其值之间的关联是常量。如果 x 是一个数组或字典(例如),你仍然可以修改、添加或删除元素。

在某些情况下,更改 const 变量的值会导致警告而不是错误。但是,这会产生不可预测的行为或破坏程序状态,因此应避免。此功能仅用于交互式使用时的便利。

来源
struct关键字
struct

Julia 中最常用的类型是结构体,指定为一个名称和一组字段。

struct Point
    x
    y
end

字段可以具有类型限制,这些限制可以参数化。

struct Point{X}
    x::X
    y::Float64
end

结构体还可以通过 <: 语法声明抽象超类型。

struct Point <: AbstractPoint
    x
    y
end

struct 默认情况下是不可变的;在构造后无法修改这些类型的实例。使用 mutable struct 而不是声明实例可以修改的类型。

有关更多详细信息(例如如何定义构造函数),请参阅 复合类型 手册部分。

来源
Base.@kwdef
@kwdef typedef

这是一个帮助宏,它会自动为表达式 typedef 中声明的类型定义基于关键字的构造函数,该表达式必须是 structmutable struct 表达式。默认参数通过声明形式为 field::T = defaultfield = default 的字段提供。如果没有提供默认值,则关键字参数将成为结果类型构造函数中的必需关键字参数。

仍然可以定义内部构造函数,但至少应该有一个接受与默认内部构造函数相同形式的参数(即每个字段一个位置参数),以便与关键字外部构造函数正常工作。

Julia 1.1

Base.@kwdef 用于参数化结构体以及具有超类型的结构体,需要 Julia 1.1 或更高版本。

Julia 1.9

从 Julia 1.9 开始,此宏被导出。

示例

julia> @kwdef struct Foo
           a::Int = 1         # specified default
           b::String          # required keyword
       end
Foo

julia> Foo(b="hi")
Foo(1, "hi")

julia> Foo()
ERROR: UndefKeywordError: keyword argument `b` not assigned
Stacktrace:
[...]
来源
abstract type关键字
abstract type

abstract type 声明一个不能实例化的类型,并且仅用作类型图中的节点,从而描述相关具体类型的集合:这些具体类型是其后代。抽象类型形成了概念层次结构,使 Julia 的类型系统不仅仅是对象实现的集合。例如。

abstract type Number end
abstract type Real <: Number end

Number 没有超类型,而 RealNumber 的抽象子类型。

来源
primitive type关键字
primitive type

primitive type 声明一个具体类型,其数据仅包含一系列位。整数和浮点数是基本类型的经典示例。一些示例内置基本类型声明

primitive type Char 32 end
primitive type Bool <: Integer 8 end

名称后的数字表示类型所需的存储位数。目前,仅支持 8 位的倍数大小。Bool 声明显示了如何可选地声明基本类型为某个超类型的子类型。

来源
where关键字
where

where 关键字创建一个类型,该类型是其他类型的迭代联合,遍历某个变量的所有值。例如,Vector{T} where T<:Real 包含所有 Vector,其中元素类型是某种 Real 数。

如果省略,绑定的变量默认值为 Any

Vector{T} where T    # short for `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, ...} 将类型“应用”于参数值时变量被替换的顺序一致。

来源
...关键字
...

“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
来源
;关键字
;

; 在 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) # without the ; or a trailing comma this would assign to 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; # set variables b and x using property destructuring

julia> b, x
(2, 1)

julia> ; # upon typing ;, the prompt changes (in place) to: shell>
shell> echo hello
hello
来源
=关键字
=

= 是赋值运算符。

  • 对于变量 a 和表达式 ba = 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

示例

a 赋值给 b 不会创建 b 的副本;而是使用 copydeepcopy

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])

在越界索引处赋值不会扩展集合。如果集合是 Vector,则可以使用 push!append! 来扩展它。

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

[] 赋值不会从集合中消除元素;而是使用 filter!

julia> a = collect(1:3); a[a .<= 1] = []
ERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations
[...]

julia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1]
2-element Array{Int64, 1}:
 2
 3
来源
?:关键字
a ? b : c

条件语句的简短形式;读作“如果 a,则计算 b,否则计算 c”。也被称为 三元运算符

此语法等效于 if a; b else c end,但通常用于强调用作较大表达式一部分的值 bc,而不是评估 bc 可能产生的副作用。

有关详细信息,请参阅手册中关于 控制流 的部分。

示例

julia> x = 1; y = 2;

julia> x > y ? println("x is larger") : println("y is larger")
y is larger
来源

标准模块

Main模块
Main

Main 是顶层模块,Julia 从将 Main 设置为当前模块开始。在提示符处定义的变量将进入 Main,而 varinfo 将列出 Main 中的变量。

julia> @__MODULE__
Main
来源
Core模块
Core

Core 是包含所有被认为是语言“内置”的标识符的模块,即语言的核心部分,而不是库。每个模块都隐式指定 using Core,因为如果没有这些定义,就无法执行任何操作。

来源
Base模块
Base

Julia 的基本库。Base 是一个包含基本功能的模块(base/ 的内容)。所有模块都隐式包含 using Base,因为这在绝大多数情况下都是必需的。

来源

Base 子模块

Base.Docs模块
Docs

Docs 模块提供 @doc 宏,可用于设置和检索 Julia 对象的文档元数据。

有关详细信息,请参阅手册中关于 文档 的部分。

来源
Base.Sys模块

提供用于检索有关硬件和操作系统的的信息的方法。

来源
Base.GC模块
Base.GC

包含垃圾回收实用程序的模块。

来源

所有对象

Core.:===函数
===(x,y) -> Bool
≡(x,y) -> Bool

确定 xy 是否完全相同,从这个意义上讲,没有程序可以区分它们。首先比较 xy 的类型。如果类型相同,则可变对象按内存地址进行比较,不可变对象(如数字)则按位级内容进行比较。此函数有时称为“egal”。它始终返回 Bool 值。

示例

julia> a = [1, 2]; b = [1, 2];

julia> a == b
true

julia> a === b
false

julia> a === a
true
来源
Core.isa函数
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
来源
Base.isequal函数
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)使用的比较函数。isequal(x,y) 必须意味着 hash(x) == hash(y)

这通常意味着具有自定义 ==isequal 方法的类型必须实现相应的 hash 方法(反之亦然)。集合通常通过递归调用所有内容的 isequal 来实现 isequal

此外,isequalisless 相连,它们一起定义了一个固定的全序,其中 isequal(x, y)isless(x, y)isless(y, x) 中必须只有一个为 true(另外两个为 false)。

标量类型通常不需要单独实现 isequal==,除非它们代表浮点数,并且可以采用比作为通用回退提供的更有效的实现(基于 isnansignbit==)。

示例

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

julia> isequal(missing, missing)
true
来源
isequal(x)

创建一个函数,使用 isequal 将其参数与 x 进行比较,即等效于 y -> isequal(y, x) 的函数。

返回的函数的类型为 Base.Fix2{typeof(isequal)},可用于实现专用方法。

来源
Base.isless函数
isless(x, y)

根据固定的全序(与 isequal 一起定义),测试 x 是否小于 yisless 未针对所有类型的对 (x, y) 定义。但是,如果已定义,则应满足以下条件

  • 如果 isless(x, y) 已定义,则 isless(y, x)isequal(x, y) 也已定义,并且这三个中只有一个产生 true
  • isless 定义的关系是传递的,即,isless(x, y) && isless(y, z) 意味着 isless(x, z)

通常无序的值(如 NaN)在常规值之后排序。missing 值在最后排序。

这是 sort! 使用的默认比较方法。

实现

具有全序的非数值类型应实现此函数。数值类型仅在具有特殊值(如 NaN)时才需要实现此函数。具有偏序的类型应实现 <。有关如何定义可用于排序和相关函数的替代排序方法的详细信息,请参阅 替代排序 的文档。

示例

julia> isless(1, 3)
true

julia> isless("Red", "Blue")
false
来源
Base.isunordered函数
isunordered(x)

如果 x 是根据 < 不可排序的值(如 NaNmissing),则返回 true

使用此谓词评估为 true 的值可以使用其他排序(如 isless)进行排序。

Julia 1.7

此函数需要 Julia 1.7 或更高版本。

来源
Base.ifelse函数
ifelse(condition::Bool, x, y)

如果 conditiontrue,则返回 x,否则返回 y。这与 ?if 不同,因为它是一个普通的函数,所以所有参数都会先被求值。在某些情况下,使用 ifelse 而不是 if 语句可以消除生成的代码中的分支,并在紧凑循环中提供更高的性能。

示例

julia> ifelse(1 > 2, 1, 2)
2
来源
Core.typeassert函数
typeassert(x, type)

除非 x isa type,否则抛出 TypeError。语法 x::type 会调用此函数。

示例

julia> typeassert(2.5, Int)
ERROR: TypeError: in typeassert, expected Int64, got a value of type Float64
Stacktrace:
[...]
来源
Core.typeof函数
typeof(x)

获取 x 的具体类型。

另请参见 eltype

示例

julia> a = 1//2;

julia> typeof(a)
Rational{Int64}

julia> M = [1 2; 3.5 4];

julia> typeof(M)
Matrix{Float64} (alias for Array{Float64, 2})
来源
Core.tuple函数
tuple(xs...)

构造一个包含给定对象的元组。

另请参见 TuplentupleNamedTuple

示例

julia> tuple(1, 'b', pi)
(1, 'b', π)

julia> ans === (1, 'b', π)
true

julia> Tuple(Real[1, 2, pi])  # takes a collection
(1, 2, π)
来源
Base.ntuple函数
ntuple(f::Function, 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)
来源
Base.objectid函数
objectid(x) -> UInt

根据对象标识获取 x 的哈希值。

如果 x === y,则 objectid(x) == objectid(y),并且通常当 x !== y 时,objectid(x) != objectid(y)

另请参见 hashIdDict

来源
Base.hash函数
hash(x[, h::UInt]) -> UInt

计算一个整数哈希码,使得 isequal(x,y) 意味着 hash(x)==hash(y)。可选的第二个参数 h 是另一个要与结果混合的哈希码。

新的类型应该实现 2 参数形式,通常通过递归地调用 2 参数 hash 方法来实现,以便将内容的哈希值彼此混合(以及与 h 混合)。通常,任何实现 hash 的类型也应该实现自己的 ==(因此 isequal)来保证上述属性。支持减法(运算符 -)的类型也应该实现 widen,这是对异构数组中的值进行哈希处理所必需的。

当一个新的 Julia 进程启动时,哈希值可能会发生变化。

julia> a = hash(10)
0x95ea2955abd45275

julia> hash(10, a) # only use the output of another hash function as the second argument
0xd42bad54a8575b16

另请参见:objectidDictSet

来源
Base.finalizer函数
finalizer(f, x)

注册一个函数 f(x),当没有程序可访问的引用指向 x 时,该函数会被调用,并返回 xx 的类型必须是 mutable struct,否则函数将抛出异常。

f 不能导致任务切换,这排除了大多数 I/O 操作,例如 println。使用 @async 宏(将上下文切换延迟到最终器之外)或 ccall 直接在 C 中调用 IO 函数可能有助于调试目的。

请注意,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

可以在对象构造时注册最终器。在以下示例中,请注意我们隐式地依赖于最终器返回新创建的 mutable struct x

示例

mutable struct MyMutableStruct
    bar
    function MyMutableStruct(bar)
        x = new(bar)
        f(t) = @async println("Finalizing $t.")
        finalizer(f, x)
    end
end
来源
Base.copy函数
copy(x)

创建 x 的浅拷贝:外部结构被复制,但并非所有内部值。例如,复制数组会生成一个新的数组,该数组与原始数组具有相同元素。

另请参见 copy!copyto!deepcopy

来源
Base.deepcopy函数
deepcopy(x)

创建 x 的深拷贝:所有内容都会被递归地复制,从而产生一个完全独立的对象。例如,深拷贝数组会生成一个新的数组,其元素是原始元素的深拷贝。对对象调用 deepcopy 通常应该与序列化它然后反序列化它具有相同的效果。

虽然通常没有必要,但用户定义的类型可以通过定义函数 deepcopy_internal(x::T, dict::IdDict)(不应该被其他方式使用)的专门版本来覆盖默认的 deepcopy 行为,其中 T 是要为其专门化的类型,而 dict 跟踪到目前为止在递归中复制的对象。在定义中,deepcopy_internal 应该被用作 deepcopy 的替代品,并且 dict 变量应该在返回之前根据需要进行更新。

来源
Base.getproperty函数
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 # fallback to getfield
               return getfield(obj, sym)
           end
       end

julia> obj = MyType(1);

julia> obj.special
2

julia> obj.x
1

只有在必要时才应该重载 getproperty,因为如果语法 obj.f 的行为不寻常,可能会令人困惑。另外请注意,使用方法通常更可取。有关更多信息,另请参见此风格指南文档:优先使用导出方法而不是直接字段访问

另请参见 getfieldpropertynamessetproperty!

来源
Base.setproperty!函数
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)

Julia 1.8

setproperty! 对模块的要求至少为 Julia 1.8。

另请参见 setfield!propertynamesgetproperty

来源
Base.replaceproperty!函数
replaceproperty!(x, f::Symbol, expected, desired, success_order::Symbol=:not_atomic, fail_order::Symbol=success_order)

根据 egal,对 x.fexpecteddesired 执行比较和交换操作。语法 @atomic_replace! x.f expected => desired 可以用作函数调用形式的替代品。

另请参见 replacefield!setproperty!

来源
Base.swapproperty!函数
swapproperty!(x, f::Symbol, v, order::Symbol=:not_atomic)

语法 @atomic a.b, _ = c, a.b 返回 (c, swapproperty!(a, :b, c, :sequentially_consistent)),其中必须有一方包含的 getproperty 表达式是相同的。

另请参见 swapfield!setproperty!

来源
Base.modifyproperty!函数
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 函数。

另请参见 modifyfield!setproperty!

来源
Base.propertynames函数
propertynames(x, private=false)

获取一个元组或一个包含对象 x 的属性(x.property)的向量。这通常与 fieldnames(typeof(x)) 相同,但重载 getproperty 的类型通常也应该重载 propertynames 以获取该类型实例的属性。

propertynames(x) 可能只返回作为 x 的文档化接口一部分的“公共”属性名。如果您希望它还返回用于内部使用的“私有”属性名,则将 true 传递给可选的第二个参数。x. 上的 REPL 选项卡补全只显示 private=false 的属性。

另请参见:haspropertyhasfield

来源
Base.hasproperty函数
hasproperty(x, s::Symbol)

返回一个布尔值,指示对象 x 是否将 s 作为其自身的属性之一。

Julia 1.2

此函数至少需要 Julia 1.2。

另请参见:propertynameshasfield

来源
Core.getfield函数
getfield(value, name::Symbol, [order::Symbol])
getfield(value, i::Int, [order::Symbol])

通过名称或位置从复合 value 中提取一个字段。可以选择定义操作的顺序。如果该字段声明为 @atomic,则强烈建议该规范与存储到该位置的存储兼容。否则,如果没有声明为 @atomic,则如果指定,此参数必须是 :not_atomic。另请参见 getpropertyfieldnames

示例

julia> a = 1//2
1//2

julia> getfield(a, :num)
1

julia> a.num
1

julia> getfield(a, 1)
1
来源
Core.setfield!函数
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
来源
Core.modifyfield!函数
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

如果硬件支持(例如,原子增量),则这可能会被优化为适当的硬件指令,否则它将使用循环。

来源
Core.replacefield!函数
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)

如果硬件支持,则这可能会被优化为适当的硬件指令,否则它将使用循环。

来源
Core.swapfield!函数
swapfield!(value, name::Symbol, x, [order::Symbol])
swapfield!(value, i::Int, x, [order::Symbol])

这些以原子方式执行同时获取和设置字段的操作

y = getfield(value, name)
setfield!(value, name, x)
return y
来源
Core.isdefined函数
isdefined(m::Module, s::Symbol, [order::Symbol])
isdefined(object, s::Symbol, [order::Symbol])
isdefined(object, index::Int, [order::Symbol])

测试全局变量或对象字段是否已定义。参数可以是模块和符号,也可以是复合对象和字段名称(作为符号)或索引。可以选择为操作定义顺序。如果该字段声明为@atomic,则强烈建议规范与该位置的存储兼容。否则,如果未声明为@atomic,则如果指定,此参数必须为:not_atomic

要测试数组元素是否已定义,请使用 isassigned 而不是。

另请参见 @isdefined

示例

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
来源
Core.getglobal函数
getglobal(module::Module, name::Symbol, [order::Symbol=:monotonic])

从模块module检索绑定name的值。可以选择为操作定义原子顺序,否则默认为单调。

虽然使用 getfield 访问模块绑定仍然受支持以保持兼容性,但应始终优先使用 getglobal,因为 getglobal 允许控制原子顺序(getfield 始终是单调的),并且更好地表明了代码的意图,对用户和编译器都是如此。

大多数用户无需直接调用此函数 - 除了一些非常特殊的用例外,应首选 getproperty 函数或相应的语法(即 module.name)。

Julia 1.9

此函数需要 Julia 1.9 或更高版本。

另请参见 getpropertysetglobal!

示例

julia> a = 1
1

julia> module M
       a = 2
       end;

julia> getglobal(@__MODULE__, :a)
1

julia> getglobal(M, :a)
2
来源
Core.setglobal!函数
setglobal!(module::Module, name::Symbol, x, [order::Symbol=:monotonic])

将模块module中绑定name的值设置为x。不执行类型转换,因此如果已为绑定声明类型,则x必须是适当的类型,否则会抛出错误。

此外,可以为此操作指定原子顺序,否则默认为单调。

用户通常会通过 setproperty! 函数或相应的语法(即 module.name = x)访问此功能,因此这仅适用于非常特殊的用例。

Julia 1.9

此函数需要 Julia 1.9 或更高版本。

另请参见 setproperty!getglobal

示例

julia> module M end;

julia> M.a  # same as `getglobal(M, :a)`
ERROR: UndefVarError: `a` not defined

julia> setglobal!(M, :a, 1)
1

julia> M.a
1
来源
Base.@isdefined
@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)

julia> f()
false
true
来源
Base.convert函数
convert(T, x)

x转换为类型T的值。

如果TInteger 类型,如果x不能用T表示,则会引发 InexactError,例如,如果x不是整数值,或者在T支持的范围内。

示例

julia> convert(Int, 3.0)
3

julia> convert(Int, 3.5)
ERROR: InexactError: Int64(3.5)
Stacktrace:
[...]

如果TAbstractFloat 类型,则它将返回T可以表示的与x最接近的值。

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

另请参见: roundtruncoftypereinterpret

来源
Base.promote函数
promote(xs...)

将所有参数转换为通用类型,并返回它们全部(作为元组)。如果无法转换任何参数,则会引发错误。

另请参见: promote_typepromote_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
来源
Base.oftype函数
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
来源
Base.widen函数
widen(x)

如果x是类型,则返回一个“更大”的类型,定义为对于类型x可以保存的任何值的组合,算术运算+-都保证不会溢出或丢失精度。

对于小于 128 位的固定大小整数类型,widen 将返回一个位数加倍的类型。

如果x是值,则将其转换为 widen(typeof(x))

示例

julia> widen(Int32)
Int64

julia> widen(1.5f0)
1.5
来源
Base.identity函数
identity(x)

恒等函数。返回其参数。

另请参见: oneoneunitLinearAlgebraI

示例

julia> identity("Well, what did you expect?")
"Well, what did you expect?"
来源
Core.WeakRef类型
WeakRef(x)

w = WeakRef(x) 构造对 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           # a reference is maintained via `x`
WeakRef("a string")

julia> x = nothing # clear reference

julia> GC.gc()

julia> w
WeakRef(nothing)
来源

类型的属性

类型关系

Base.supertype函数
supertype(T::DataType)

返回 DataType T 的超类型。

示例

julia> supertype(Int32)
Signed
来源
Core.Type类型
Core.Type{T}

Core.Type 是一个抽象类型,其所有类型对象都是其实例。单例类型 Core.Type{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
来源
Core.DataType类型
DataType <: Type{T}

DataType 代表具有名称、显式声明的超类型以及可选参数的显式声明类型。系统中的每个具体值都是某个 DataType 的实例。

示例

julia> typeof(Real)
DataType

julia> typeof(Int)
DataType

julia> struct Point
           x::Int
           y
       end

julia> typeof(Point)
DataType
来源
Core.:<:函数
<:(T1, T2)

子类型运算符:当且仅当类型 T1 的所有值也是类型 T2 的值时,返回 true

示例

julia> Float64 <: AbstractFloat
true

julia> Vector{Int} <: AbstractArray
true

julia> Matrix{Float64} <: Matrix{AbstractFloat}
false
来源
Base.:>:函数
>:(T1, T2)

超类型运算符,等效于 T2 <: T1

来源
Base.typejoin函数
typejoin(T, S, ...)

返回类型 TS 的最近共同祖先,即它们共同继承的最窄类型。对其他可变参数进行递归。

示例

julia> typejoin(Int, Float64)
Real

julia> typejoin(Int, Float64, ComplexF32)
Number
来源
Base.typeintersect函数
typeintersect(T::Type, S::Type)

计算包含 TS 交集的类型。通常,这将是最小的此类类型或接近它的类型。

来源
Base.promote_type函数
promote_type(type1, type2, ...)

提升是指将混合类型的值转换为单个通用类型。promote_type 代表当运算符(通常是数学运算符)被给予不同类型的参数时,Julia 中的默认提升行为。promote_type 通常会尝试返回一个类型,该类型至少可以近似表示任一输入类型的大多数值,而不会过度扩展。允许一些损失;例如,promote_type(Int64, Float64) 返回 Float64,即使严格来说,并非所有 Int64 值都可以精确地表示为 Float64 值。

另请参见: promotepromote_typejoinpromote_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_rulepromote_type 在内部调用 promote_rule 来确定类型。直接重载 promote_type 会导致歧义错误。

来源
Base.promote_rule函数
promote_rule(type1, type2)

指定当给定类型为 type1type2 的值时,promote 应该使用什么类型。此函数不应直接调用,但应为新类型添加定义,以适当地使用它。

来源
Base.promote_typejoin函数
promote_typejoin(T, S)

计算包含 TS 的类型,它可以是两种类型的父级,也可以是 Union(如果适用)。回退到 typejoin

请参阅 promotepromote_type 而不是。

示例

julia> Base.promote_typejoin(Int, Float64)
Real

julia> Base.promote_type(Int, Float64)
Float64
来源
Base.isdispatchtuple函数
isdispatchtuple(T)

确定类型 T 是否是元组“叶类型”,这意味着它可以作为类型签名出现在调度中,并且没有可以出现在调用中的子类型(或超类型)。

来源

声明结构

Base.ismutable函数
ismutable(v) -> Bool

当且仅当值 v 是可变的时,返回 true。有关不可变性的讨论,请参阅 可变复合类型。请注意,此函数作用于值,因此如果您给它一个 DataType,它将告诉您该类型的某个值是可变的。

注意

由于技术原因,ismutable 会针对某些特殊类型(例如 StringSymbol)的值返回 true,即使它们不能以允许的方式进行变异。

另请参见 isbitsisstructtype

示例

julia> ismutable(1)
false

julia> ismutable([1,2])
true
Julia 1.5

此函数至少需要 Julia 1.5。

来源
Base.isimmutable函数
isimmutable(v) -> Bool
警告

考虑使用 !ismutable(v) 而不是,因为 isimmutable(v) 将在将来的版本中被 !ismutable(v) 替换。(从 Julia 1.5 开始)

当且仅当值 v 不可变时,返回 true。有关不可变性的讨论,请参阅 可变复合类型。请注意,此函数作用于值,因此如果您给它一个类型,它将告诉您 DataType 的某个值是可变的。

示例

julia> isimmutable(1)
true

julia> isimmutable([1,2])
false
来源
Base.ismutabletype函数
ismutabletype(T) -> Bool

确定类型 T 是否被声明为可变类型(即使用 mutable struct 关键字)。

Julia 1.7

此函数至少需要 Julia 1.7。

来源
Base.isabstracttype函数
isabstracttype(T)

确定类型T是否声明为抽象类型(即使用abstract type语法)。

示例

julia> isabstracttype(AbstractArray)
true

julia> isabstracttype(Vector)
false
来源
Base.isprimitivetype函数
isprimitivetype(T) -> Bool

确定类型T是否声明为原始类型(即使用primitive type语法)。

来源
Base.issingletontype函数
Base.issingletontype(T)

确定类型T是否只有一个可能的实例;例如,一个没有字段的结构体类型。

来源
Base.isstructtype函数
isstructtype(T) -> Bool

确定类型T是否声明为结构体类型(即使用structmutable struct关键字)。

来源
Base.nameof方法
nameof(t::DataType) -> Symbol

将(可能被UnionAll包裹的)DataType的名称(不包含其父模块)获取为一个符号。

示例

julia> module Foo
           struct S{T}
           end
       end
Foo

julia> nameof(Foo.S{T} where T)
:S
来源
Base.fieldnames函数
fieldnames(x::DataType)

获取一个包含DataType字段名称的元组。

另请参阅 propertynames, hasfield.

示例

julia> fieldnames(Rational)
(:num, :den)

julia> fieldnames(typeof(1+im))
(:re, :im)
来源
Base.fieldname函数
fieldname(x::DataType, i::Integer)

获取DataType中第i个字段的名称。

示例

julia> fieldname(Rational, 1)
:num

julia> fieldname(Rational, 2)
:den
来源
Core.fieldtype函数
fieldtype(T, name::Symbol | index::Int)

确定复合DataTypeT中一个字段(通过名称或索引指定)的声明类型。

示例

julia> struct Foo
           x::Int64
           y::String
       end

julia> fieldtype(Foo, :x)
Int64

julia> fieldtype(Foo, 2)
String
来源
Base.fieldtypes函数
fieldtypes(T::Type)

复合DataTypeT中所有字段的声明类型,以元组形式返回。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

示例

julia> struct Foo
           x::Int64
           y::String
       end

julia> fieldtypes(Foo)
(Int64, String)
来源
Base.fieldcount函数
fieldcount(t::Type)

获取给定类型实例所具有的字段数量。如果类型过于抽象无法确定,则会抛出错误。

来源
Base.hasfield函数
hasfield(T::Type, name::Symbol)

返回一个布尔值,指示T是否将name作为其自身的字段之一。

另请参阅 fieldnames, fieldcount, hasproperty.

Julia 1.2

此函数至少需要 Julia 1.2。

示例

julia> struct Foo
            bar::Int
       end

julia> hasfield(Foo, :bar)
true

julia> hasfield(Foo, :x)
false
来源
Core.nfields函数
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,它有一个字段。

来源
Base.isconst函数
isconst(m::Module, s::Symbol) -> Bool

确定全局变量是否在给定模块m中声明为const

来源
isconst(t::DataType, s::Union{Int,Symbol}) -> Bool

确定字段s是否在给定类型t中声明为const

来源
Base.isfieldatomic函数
isfieldatomic(t::DataType, s::Union{Int,Symbol}) -> Bool

确定字段s是否在给定类型t中声明为@atomic

来源

内存布局

Base.sizeof方法
sizeof(T::DataType)
sizeof(obj)

给定DataTypeT的规范二进制表示形式的大小(以字节为单位),如果有的话。或者,如果obj不是DataType,则为对象obj的大小(以字节为单位)。

另请参阅 Base.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) # not the sum of `sizeof` of fields due to padding
16

julia> sizeof(Int64) + sizeof(Bool) # different from above
9

如果DataTypeT没有特定大小,则会抛出错误。

julia> sizeof(AbstractArray)
ERROR: Abstract type AbstractArray does not have a definite size.
Stacktrace:
[...]
来源
Base.isconcretetype函数
isconcretetype(T)

确定类型T是否为具体类型,这意味着它可以有直接实例(值x,使得typeof(x) === T)。

另请参阅:isbits, 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
来源
Base.isbitstype函数
isbitstype(T)

如果类型T是“纯数据”类型,则返回true,这意味着它是不可变的,并且不包含对其他值的引用,只包含primitive类型和其他isbitstype类型。典型的例子是数值类型,例如UInt8, Float64, 和 Complex{Float64}。这类别类型很重要,因为它们可以作为类型参数,可能不会跟踪isdefined / isassigned状态,并且具有与C兼容的已定义布局。

另请参阅 isbits, isprimitivetype, ismutable.

示例

julia> isbitstype(Complex{Float64})
true

julia> isbitstype(Complex)
false
来源
Base.fieldoffset函数
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)
来源
Base.datatype_alignment函数
Base.datatype_alignment(dt::DataType) -> Int

此类型实例的内存分配最小对齐方式。可以在任何isconcretetype上调用。

来源
Base.datatype_haspadding函数
Base.datatype_haspadding(dt::DataType) -> Bool

返回此类型实例的字段是否在内存中打包,没有中间填充字节。可以在任何isconcretetype上调用。

来源
Base.datatype_pointerfree函数
Base.datatype_pointerfree(dt::DataType) -> Bool

返回此类型实例是否可以包含对gc管理内存的引用。可以在任何isconcretetype上调用。

来源

特殊值

Base.typemin函数
typemin(T)

给定(实数)数值DataTypeT可表示的最低值。

另请参阅:floatmin, typemax, eps.

示例

julia> typemin(Int8)
-128

julia> typemin(UInt32)
0x00000000

julia> typemin(Float16)
-Inf16

julia> typemin(Float32)
-Inf32

julia> nextfloat(-Inf32)  # smallest finite Float32 floating point number
-3.4028235f38
来源
Base.typemax函数
typemax(T)

给定(实数)数值DataType可表示的最高值。

另请参阅:floatmax, typemin, eps.

示例

julia> typemax(Int8)
127

julia> typemax(UInt32)
0xffffffff

julia> typemax(Float64)
Inf

julia> typemax(Float32)
Inf32

julia> floatmax(Float32)  # largest finite Float32 floating point number
3.4028235f38
来源
Base.floatmin函数
floatmin(T = Float64)

返回浮点类型T可表示的最小正规数。

示例

julia> floatmin(Float16)
Float16(6.104e-5)

julia> floatmin(Float32)
1.1754944f-38

julia> floatmin()
2.2250738585072014e-308
来源
Base.floatmax函数
floatmax(T = Float64)

返回浮点类型T可表示的最大有限数。

另请参阅:typemax, floatmin, eps.

示例

julia> floatmax(Float16)
Float16(6.55e4)

julia> floatmax(Float32)
3.4028235f38

julia> floatmax()
1.7976931348623157e308

julia> typemax(Float64)
Inf
来源
Base.maxintfloat函数
maxintfloat(T=Float64)

给定浮点类型T(默认为Float64)中可精确表示的最大连续整数值浮点数。

也就是说,maxintfloat返回最小的正整数值浮点数n,使得n+1不能在类型T中精确表示。

当需要Integer类型的值时,使用Integer(maxintfloat(T))

来源
maxintfloat(T, S)

给定浮点类型T中可表示的最大连续整数,并且也不超过整数类型S可表示的最大整数。等效地,它是maxintfloat(T)typemax(S)的最小值。

来源
Base.eps方法
eps(::Type{T}) where T<:AbstractFloat
eps()

返回浮点类型T(默认情况下为T = Float64)的机器ε。这被定义为1和typeof(one(T))可表示的下一个最大值之间的差距,并且等效于eps(one(T))。(由于eps(T)T相对误差的界限,因此它是一个“无量纲”量,类似于one。)

示例

julia> eps()
2.220446049250313e-16

julia> eps(Float32)
1.1920929f-7

julia> 1.0 + eps()
1.0000000000000002

julia> 1.0 + eps()/2
1.0
来源
Base.eps方法
eps(x::AbstractFloat)

返回x最后一个位置的单位(ulp)。这是x处连续可表示的浮点值之间的距离。在大多数情况下,如果x两侧的距离不同,则采用较大者,即

eps(x) == max(x-prevfloat(x), nextfloat(x)-x)

此规则的例外情况是最小和最大有限值(例如,nextfloat(-Inf)prevfloat(Inf)对于Float64),它们会四舍五入到较小的值。

此行为的原因是eps对浮点舍入误差进行了限制。在默认的RoundNearest舍入模式下,如果$y$是实数,而$x$$y$的最近浮点数,那么

\[|y-x| \leq \operatorname{eps}(x)/2.\]

另请参阅:nextfloat, issubnormal, 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)      # largest finite Float64
1.7976931348623157e308

julia> x + eps(x)/2            # rounds up
Inf

julia> x + prevfloat(eps(x)/2) # rounds down
1.7976931348623157e308
来源
Base.instances函数
instances(T::Type)

返回给定类型的所有实例的集合,如果适用的话。主要用于枚举类型(参见@enum)。

示例

julia> @enum Color red blue green

julia> instances(Color)
(red, blue, green)
来源

特殊类型

Core.Any类型
Any::DataType

Any是所有类型的并集。它具有定义属性isa(x, Any) == true,适用于任何x。因此,Any描述了所有可能值的整个宇宙。例如,IntegerAny的一个子集,它包含IntInt8和其他整数类型。

来源
Core.Union类型
Union{Types...}

类型联合是一个抽象类型,它包含其所有参数类型的任何实例。空联合Union{}是Julia的底部类型。

示例

julia> IntOrString = Union{Int,AbstractString}
Union{Int64, AbstractString}

julia> 1 isa IntOrString
true

julia> "Hello!" isa IntOrString
true

julia> 1.0 isa IntOrString
false
来源
Union{}关键字
Union{}

Union{} 是一个空类型 Union,它没有任何值。也就是说,对于任何 x,它具有定义属性 isa(x, Union{}) == falseBase.Bottom 被定义为它的别名,Union{} 的类型为 Core.TypeofBottom

示例

julia> isa(nothing, Union{})
false
来源
Core.UnionAll类型
UnionAll

对类型参数所有值的类型联合。UnionAll 用于描述参数类型,其中一些参数的值未知。

示例

julia> typeof(Vector)
UnionAll

julia> typeof(Vector{Int})
DataType
来源
Core.Tuple类型
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,) 编写,因为 (1) 只是一个带括号的值。() 表示空(长度为 0)元组。

元组可以通过使用 Tuple 类型作为构造函数从迭代器构建

julia> Tuple(["a", 1])
("a", 1)

julia> Tuple{String, Float64}(["a", 1])
("a", 1.0)

元组类型在其参数中是协变的:Tuple{Int}Tuple{Any} 的子类型。因此 Tuple{Any} 被认为是抽象类型,只有当元组类型的参数是具体类型时,元组类型才是具体的。元组没有字段名称;字段只能通过索引访问。元组类型可以具有任意数量的参数。

参见关于 元组类型 的手册部分。

另见 VarargNTuplentupletupleNamedTuple

来源
Core.NTuple类型
NTuple{N, T}

表示长度为 N 的元组类型的一种简洁方式,其中所有元素都具有类型 T

示例

julia> isa((1, 2, 3, 4, 5, 6), NTuple{6, Int})
true

另见 ntuple

来源
Core.NamedTuple类型
NamedTuple

顾名思义,NamedTuple 是命名 Tuple。也就是说,它们是类似元组的值集合,其中每个条目都有一个唯一的名称,表示为 Symbol。与 Tuple 一样,NamedTuple 是不可变的;在构造后,名称和值都不能就地修改。

命名元组可以作为带键的元组文字创建,例如 (a=1, b=2),或者作为带有左括号后的分号的元组文字创建,例如 (; a=1, b=2)(此形式还接受程序生成的名称,如下所述),或者使用 NamedTuple 类型作为构造函数,例如 NamedTuple{(:a, :b)}((1,2))

可以使用字段访问语法访问命名元组中与名称关联的值,例如 x.a,或者使用 getindex,例如 x[:a]x[(:a, :b)]。可以使用 keys 获取名称元组,可以使用 values 获取值元组。

注意

NamedTuple 的迭代产生不带名称的。(见下面的例子。)要迭代名称-值对,请使用 pairs 函数。

@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) # the final b overwrites the value from nt1
(a = 1, b = 20, c = 3, d = 4)

julia> (; zip(keys, values)...) # zip yields tuples such as (:a, 1)
(a = 1, b = 2, c = 3)

与关键字参数一样,标识符和点表达式暗示名称

julia> x = 0
0

julia> t = (; x)
(x = 0,)

julia> (; t.x)
(x = 0,)
Julia 1.5

来自标识符和点表达式的隐式名称从 Julia 1.5 开始可用。

Julia 1.7

从 Julia 1.7 开始,可以使用带有多个 Symbolgetindex 方法。

来源
Base.@NamedTuple
@NamedTuple{key1::Type1, key2::Type2, ...}
@NamedTuple begin key1::Type1; key2::Type2; ...; end

此宏为声明 NamedTuple 类型提供了一种更方便的语法。它返回一个具有给定键和类型的 NamedTuple 类型,等效于 NamedTuple{(:key1, :key2, ...), Tuple{Type1,Type2,...}}。如果省略 ::Type 声明,则将其视为 Anybegin ... end 形式允许声明跨越多行(类似于 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}
Julia 1.5

此宏从 Julia 1.5 开始可用。

来源
Base.@Kwargs
@Kwargs{key1::Type1, key2::Type2, ...}

此宏提供了一种方便的方法,可以使用与 @NamedTuple 相同的语法构造关键字参数的类型表示。例如,当我们有一个类似于 func([positional arguments]; kw1=1.0, kw2="2") 的函数调用时,我们可以使用此宏来构造关键字参数的内部类型表示,如 @Kwargs{kw1::Float64, kw2::String}。宏语法专门设计用于简化在堆栈跟踪视图中打印关键字方法的签名类型。

julia> @Kwargs{init::Int} # the internal representation of keyword arguments
Base.Pairs{Symbol, Int64, Tuple{Symbol}, @NamedTuple{init::Int64}}

julia> sum("julia"; init=1)
ERROR: MethodError: no method matching +(::Char, ::Char)

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
Julia 1.10

此宏从 Julia 1.10 开始可用。

来源
Base.Val类型
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"
来源
Core.Vararg常量
Vararg{T,N}

元组类型 Tuple 的最后一个参数可以是特殊值 Vararg,它表示任意数量的尾随元素。Vararg{T,N} 对应于恰好 N 个类型为 T 的元素。最后 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
来源
Base.Some类型
Some{T}

Union{Some{T}, Nothing} 中使用的包装类型,用于区分没有值(nothing)和存在 nothing 值(即 Some(nothing))。

使用 something 访问 Some 对象包装的值。

来源
Base.something函数
something(x...)

返回参数中第一个不等于 nothing 的值(如果有)。否则抛出错误。类型为 Some 的参数将被展开。

另见 coalesceskipmissing@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
来源
Base.@something
@something(x...)

something 的短路版本。

示例

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
Julia 1.7

此宏从 Julia 1.7 开始可用。

来源
Base.Enums.@enum
@enum EnumName[::BaseType] value1[=x] value2[=y]

创建具有名称 EnumNameEnum{BaseType} 子类型,以及具有 value1value2 枚举成员值的枚举成员值,以及可选的分配值 xy(分别)。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 之间转换。readwrite 自动执行这些转换。如果枚举是用非默认 BaseType 创建的,则 Integer(value1) 将返回类型为 BaseType 的整数 value1

要列出枚举的所有实例,请使用 instances,例如

julia> instances(Fruit)
(apple, orange, kiwi)

可以从枚举实例构建一个符号

julia> Symbol(apple)
:apple
来源
Core.Expr类型
Expr(head::Symbol, args...)

表示解析的 julia 代码(AST)中的复合表达式的类型。每个表达式都包含一个 head Symbol,用于标识它是哪种表达式(例如,调用、for 循环、条件语句等),以及子表达式(例如,调用的参数)。子表达式存储在名为 argsVector{Any} 字段中。

参见关于 元编程 的手册章节和开发者文档 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
来源
Core.Symbol类型
Symbol

用于表示解析的 julia 代码(AST)中的标识符的类型的对象。也常用于标识实体的名称或标签(例如,作为字典键)。Symbol 可以使用 : 引用运算符输入

julia> :name
:name

julia> typeof(:name)
Symbol

julia> x = 42
42

julia> eval(:x)
42

Symbol 也可以通过调用构造函数 Symbol(x...) 从字符串或其他值构建。

Symbol 是不可变的,它们的实现对所有具有相同名称的 Symbol 使用同一个对象。

与字符串不同,Symbol 是“原子”或“标量”实体,不支持对字符进行迭代。

来源
Core.Symbol方法
Symbol(x...) -> Symbol

通过将参数的字符串表示形式连接在一起,创建一个 Symbol

示例

julia> Symbol("my", "name")
:myname

julia> Symbol("day", 4)
:day4
来源
Core.Module类型
Module

Module 是一个独立的全局变量工作区。参见 module 和关于 模块 的手册部分以了解更多信息。

Module(name::Symbol=:anonymous, std_imports=true, default_names=true)

返回具有指定名称的模块。baremodule 对应于 Module(:ModuleName, false)

可以使用 Module(:ModuleName, false, false) 创建一个不包含任何名称的空模块。此模块不会导入 BaseCore,也不包含对自身的引用。

来源

泛型函数

Core.Function类型
Function

所有函数的抽象类型。

示例

julia> isa(+, Function)
true

julia> typeof(sin)
typeof(sin) (singleton type of function sin, subtype of Function)

julia> ans <: Function
true
来源
Base.hasmethod函数
hasmethod(f, t::Type{<:Tuple}[, kwnames]; world=get_world_counter()) -> Bool

确定给定的泛型函数是否具有与给定Tuple的函数参数类型匹配的方法,函数参数类型上界由world给出。

如果提供关键字参数名称的元组kwnames,则还会检查f匹配t的方法是否具有给定的关键字参数名称。如果匹配的方法接受可变数量的关键字参数,例如使用kwargs...,则kwnames中给出的任何名称都被视为有效。否则,提供的名称必须是方法关键字参数的子集。

另请参阅applicable.

Julia 1.2

提供关键字参数名称需要 Julia 1.2 或更高版本。

示例

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 accepts arbitrary kwargs
true
来源
Core.applicable函数
applicable(f, args...) -> Bool

确定给定的泛型函数是否具有适用于给定参数的方法。

另请参阅hasmethod.

示例

julia> function f(x, y)
           x + y
       end;

julia> applicable(f, 1)
false

julia> applicable(f, 1, 2)
true
来源
Base.isambiguous函数
Base.isambiguous(m1, m2; ambiguous_bottom=false) -> Bool

确定两个方法m1m2是否可能对于某些调用签名是模棱两可的。此测试是在同一函数的其他方法的上下文中执行的;孤立地,m1m2可能是模棱两可的,但是如果已定义了第三个解决歧义的方法,则返回false。或者,孤立地,m1m2可能是按顺序排列的,但是如果第三个方法无法与它们排序,则它们可能会一起导致歧义。

对于参数化类型,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
来源
Core.invoke函数
invoke(f, argtypes::Type, args...; kwargs...)

针对给定的泛型函数f调用匹配指定类型argtypes的指定参数args并传递关键字参数kwargs的方法。参数args必须与argtypes中指定的类型一致,即不会自动执行转换。此方法允许调用除最特定的匹配方法之外的方法,这在显式需要更一般定义的行为时很有用(通常作为同一函数的更特定方法实现的一部分)。

在使用invoke调用您没有编写的函数时要小心。对于给定的argtypes使用什么定义是一个实现细节,除非该函数明确声明以某些argtypes调用是公共 API 的一部分。例如,下面示例中f1f2之间的更改通常被认为是兼容的,因为此更改对调用者来说是不可见的,因为调用者是正常的(非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
来源
Base.@invoke
@invoke f(arg::T, ...; kwargs...)

提供了一种便捷的方式来调用invoke,方法是将@invoke f(arg1::T1, arg2::T2; kwargs...)扩展为invoke(f, Tuple{T1,T2}, arg1, arg2; kwargs...)。当省略参数的类型注释时,它将被替换为该参数的Core.Typeof。要调用参数未类型化或显式类型化为Any的方法,请使用::Any注释该参数。

它还支持以下语法

  • @invoke (x::X).f扩展为invoke(getproperty, Tuple{X,Symbol}, x, :f)
  • @invoke (x::X).f = v::V扩展为invoke(setproperty!, Tuple{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!, Tuple{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))
Julia 1.7

此宏需要 Julia 1.7 或更高版本。

Julia 1.9

从 Julia 1.9 开始,此宏被导出。

Julia 1.10

自 Julia 1.10 起支持附加语法。

来源
Base.invokelatest函数
invokelatest(f, args...; kwargs...)

调用f(args...; kwargs...),但保证执行f的最新方法。这在特殊情况下很有用,例如长时间运行的事件循环或可能调用过时版本的函数f的回调函数。(缺点是invokelatest比直接调用f稍慢,并且结果的类型无法由编译器推断。)

Julia 1.9

在 Julia 1.9 之前,此函数未导出,而是以Base.invokelatest的形式调用。

来源
Base.@invokelatest
@invokelatest f(args...; kwargs...)

提供了一种便捷的方式来调用invokelatest@invokelatest f(args...; kwargs...)将简单地扩展为Base.invokelatest(f, args...; kwargs...)

它还支持以下语法

  • @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))
Julia 1.7

此宏需要 Julia 1.7 或更高版本。

Julia 1.9

在 Julia 1.9 之前,此宏未导出,而是以Base.@invokelatest的形式调用。

Julia 1.10

附加的x.fxs[i]语法需要 Julia 1.10。

来源
new关键字
new, or new{A,B,...}

内部构造函数可用的特殊函数,用于创建新类型的对象。new{A,B,...} 形式显式指定参数化类型的参数值。有关更多信息,请参见手册中有关内部构造函数方法的部分。

来源
Base.:|>函数
|>(x, f)

中缀运算符,将函数f应用于参数x。这允许将f(g(x)) 写成x |> g |> f。当与匿名函数一起使用时,通常需要在定义周围添加括号才能获得预期的链。

示例

julia> 4 |> inv
0.25

julia> [2, 3, 5] |> sum |> inv
0.1

julia> [0 1; 2 3] .|> (x -> x^2) |> sum
14
来源
Base.:∘函数
f ∘ g

组合函数:即 (f ∘ g)(args...; kwargs...) 意味着 f(g(args...; kwargs...)) 符号可以在 Julia REPL(以及大多数经过适当配置的编辑器)中通过键入\circ<tab>输入。

函数组合也以前缀形式工作:∘(f, g)f ∘ g 相同。前缀形式支持多个函数的组合:∘(f, g, h) = f ∘ g ∘ h 和展开∘(fs...) 用于组合可迭代的函数集合。 的最后一个参数先执行。

Julia 1.4

多个函数组合需要 Julia 1.4 或更高版本。

Julia 1.5

一个函数的组合 ∘(f) 需要 Julia 1.5 或更高版本。

Julia 1.7

使用关键字参数需要 Julia 1.7 或更高版本。

示例

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::Function.

来源
Base.ComposedFunction类型
ComposedFunction{Outer,Inner} <: Function

表示两个可调用对象outer::Outerinner::Inner的组合。也就是说

ComposedFunction(outer, inner)(args...; kw...) === outer(inner(args...; kw...))

构建ComposedFunction实例的首选方法是使用组合运算符

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
Julia 1.6

ComposedFunction 需要 Julia 1.6 或更高版本。在早期版本中, 返回匿名函数。

另请参阅.

来源
Base.splat函数
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
来源
Base.Fix1类型
Fix1(f, x)

一个类型,表示两个参数函数f的部分应用版本,第一个参数固定为值“x”。换句话说,Fix1(f, x) 的行为类似于 y->f(x, y)

另请参阅Fix2.

来源
Base.Fix2类型
Fix2(f, x)

一个类型,表示两个参数函数f的部分应用版本,第二个参数固定为值“x”。换句话说,Fix2(f, x) 的行为类似于 y->f(y, x)

来源

语法

Core.eval函数
Core.eval(m::Module, expr)

在给定模块中评估表达式并返回结果。

来源
Base.MainInclude.eval函数
eval(expr)

在包含模块的全局范围内评估表达式。每个Module(除了使用baremodule定义的模块之外)都有其自己的 1 个参数的eval定义,它在该模块中评估表达式。

来源
Base.@eval
@eval [mod,] ex

使用eval将值插入其中的表达式进行评估。如果提供两个参数,第一个参数是用于评估的模块。

来源
Base.evalfile函数
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")
来源
Base.esc函数
esc(e)

仅在从宏返回的Expr上下文中有效。防止宏卫生传递将嵌入的变量转换为 gensym 变量。有关更多详细信息和示例,请参见手册中元编程章节的部分。

来源
Base.@inbounds
@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。特别是,在像上面这样的函数中使用1:length(A) 而不是 eachindex(A)并不安全地在范围内,因为对于子类型为AbstractArray的所有用户定义类型,A 的第一个索引可能不为1

来源
Base.@boundscheck
@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]"
警告

@boundscheck 注解允许您(作为库编写者)选择让其他代码使用 @inbounds 来移除您的边界检查。正如那里所述,调用者必须使用他们可以访问的信息来验证他们的访问在使用 @inbounds 之前是有效的。例如,要索引到您的 AbstractArray 子类中,这需要检查索引与其 axes 的比较。因此,@boundscheck 注解应该只在您确定其行为正确后才添加到 getindexsetindex! 实现中。

来源
Base.@inline
@inline

给编译器一个提示,表明此函数值得内联。

小型函数通常不需要 @inline 注解,因为编译器会自动进行内联。通过在较大函数上使用 @inline,可以给编译器一个额外的提示来内联它。

@inline 可以应用在函数定义之前或函数体内部。

# annotate long-form definition
@inline function longdef(x)
    ...
end

# annotate short-form definition
@inline shortdef(x) = ...

# annotate anonymous function that a `do` block creates
f() do
    @inline
    ...
end
Julia 1.8

在函数体内部使用需要至少 Julia 1.8 版本。


@inline block

给编译器一个提示,表明 block 中的调用值得内联。

# The compiler will try to inline `f`
@inline f(...)

# The compiler will try to inline `f`, `g` and `+`
@inline f(...) + g(...)
注意

调用点注释始终优先于应用于被调用函数定义的注释。

@noinline function explicit_noinline(args...)
    # body
end

let
    @inline explicit_noinline(args...) # will be inlined
end
注意

当存在嵌套的调用点注释时,最内层的注释具有优先级。

@noinline let a0, b0 = ...
    a = @inline f(a0)  # the compiler will try to inline this call
    b = f(b0)          # the compiler will NOT try to inline this call
    return a, b
end
警告

虽然调用点注释将尝试强制内联,无论成本模型如何,但它仍然有可能无法成功内联。特别是,递归调用即使被注释为 @inline,也不能被内联。

Julia 1.8

调用点注释需要至少 Julia 1.8 版本。

来源
Base.@noinline
@noinline

给编译器一个提示,表明它不应该内联函数。

小型函数通常会自动内联。通过在小型函数上使用 @noinline,可以阻止自动内联。

@noinline 可以应用在函数定义之前或函数体内部。

# annotate long-form definition
@noinline function longdef(x)
    ...
end

# annotate short-form definition
@noinline shortdef(x) = ...

# annotate anonymous function that a `do` block creates
f() do
    @noinline
    ...
end
Julia 1.8

在函数体内部使用需要至少 Julia 1.8 版本。


@noinline block

给编译器一个提示,表明它不应该内联 block 中的调用。

# The compiler will try to not inline `f`
@noinline f(...)

# The compiler will try to not inline `f`, `g` and `+`
@noinline f(...) + g(...)
注意

调用点注释始终优先于应用于被调用函数定义的注释。

@inline function explicit_inline(args...)
    # body
end

let
    @noinline explicit_inline(args...) # will not be inlined
end
注意

当存在嵌套的调用点注释时,最内层的注释具有优先级。

@inline let a0, b0 = ...
    a = @noinline f(a0)  # the compiler will NOT try to inline this call
    b = f(b0)            # the compiler will try to inline this call
    return a, b
end
Julia 1.8

调用点注释需要至少 Julia 1.8 版本。


注意

如果函数是微不足道的(例如返回常量),它可能仍然会被内联。

来源
Base.@nospecialize
@nospecialize

应用于函数参数名称,提示编译器方法实现不应该针对该参数的不同类型进行专门化,而是使用该参数的声明类型。它可以应用于形式参数列表中的参数,也可以应用于函数体中。当应用于参数时,宏必须包装整个参数表达式,例如 @nospecialize(x::Real)@nospecialize(i::Integer...),而不是只包装参数名称。在函数体内使用时,宏必须出现在语句位置,并在任何代码之前。

当没有参数使用时,它应用于父作用域的所有参数。在局部作用域中,这意味着包含函数的所有参数。在全局(顶层)作用域中,这意味着在当前模块中随后定义的所有方法。

专门化可以使用 @specialize 重置回默认值。

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
注意

@nospecialize 影响代码生成,但不影响推断:它限制了生成的本机代码的多样性,但它不会对类型推断(除了标准推断之外)施加任何限制。与 @nospecialize 一起使用 Base.@nospecializeinfer 来额外抑制推断。

示例

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 都是通用的。但是,仍然会推断出 gf 的特定返回类型,并且这仍然用于优化 fg 的调用者。

来源
Base.@nospecializeinfer
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 进行推断一次,这意味着编译器在它无法推断出它的具体返回类型时,不太可能在它身上看到过度的推断时间。如果没有 @nospecializeinferf([1.0]) 将推断出 g 的返回类型为 Float64,表明即使禁止专门化代码生成,推断也针对 g(::Vector{Float64}) 运行。

来源
Base.@constprop
@constprop setting [ex]

控制为带注释函数应用的过程间常量传播模式。

支持两个 setting

  • @constprop :aggressive [ex]: 积极地应用常量传播。对于返回类型取决于参数值的函数,这可以提高推断结果,但会增加编译时间。
  • @constprop :none [ex]: 禁用常量传播。这可以减少 Julia 可能会认为值得进行常量传播的函数的编译时间。常见情况是具有 BoolSymbol 值参数或关键字参数的函数。

@constprop 可以应用在函数定义之前或函数体内部。

# annotate long-form definition
@constprop :aggressive function longdef(x)
  ...
end

# annotate short-form definition
@constprop :aggressive shortdef(x) = ...

# annotate anonymous function that a `do` block creates
f() do
    @constprop :aggressive
    ...
end
Julia 1.10

在函数体内部使用需要至少 Julia 1.10 版本。

来源
Base.gensym函数
gensym([tag])

生成一个符号,它不会与其他变量名称(在同一个模块中)冲突。

来源
Base.@gensym
@gensym

为变量生成一个 gensym 符号。例如,@gensym x y 将转换为 x = gensym("x"); y = gensym("y")

来源
var"name"关键字
var

语法 var"#example#" 指的是名为 Symbol("#example#") 的变量,即使 #example# 不是有效的 Julia 标识符名称。

这对于与具有不同标识符构造规则的编程语言的互操作性很有用。例如,要引用 R 变量 draw.segments,您可以在您的 Julia 代码中使用 var"draw.segments"

它还用于 show 经过宏卫生处理或包含无法正常解析的变量名称的 Julia 源代码。

请注意,此语法需要解析器支持,因此它由解析器直接扩展,而不是作为普通字符串宏 @var_str 实现。

Julia 1.3

此语法需要至少 Julia 1.3 版本。

来源
Base.@goto
@goto name

@goto name 无条件跳转到 @label name 位置的语句。

@label@goto 无法创建到不同顶层语句的跳转。尝试会导致错误。要继续使用 @goto,请将 @label@goto 包含在一个块中。

来源
Base.@label
@label name

使用符号标签 name 来标记语句。标签标记了使用 @goto name 的无条件跳转的终点。

来源
Base.SimdLoop.@simd
@simd

注释 for 循环,以允许编译器采取额外措施,允许循环重新排序。

警告

此功能处于实验阶段,可能会在 Julia 的未来版本中发生变化或消失。不正确使用 @simd 宏可能会导致意外结果。

@simd for 循环中迭代的对象应为一维范围。通过使用 @simd,您断言循环具有以下几个属性

  • 以任意或重叠的顺序执行迭代是安全的,特别要考虑归约变量。
  • 对归约变量的浮点运算可以重新排序或合并,这可能导致与不使用 @simd 时不同的结果。

在许多情况下,Julia 能够在不使用 @simd 的情况下自动矢量化内部 for 循环。使用 @simd 可以给编译器一些额外的空间,使其在更多情况下成为可能。无论哪种情况,您的内部循环都应具有以下属性,以允许矢量化

  • 循环必须是最内层循环。
  • 循环体必须是直线代码。因此,目前需要 @inbounds 用于所有数组访问。如果安全地无条件地评估所有操作数,编译器有时可以将短 &&||?: 表达式转换为直线代码。如果安全地这样做,请考虑在循环中使用 ifelse 函数代替 ?:
  • 访问必须具有步长模式,不能是“收集”(随机索引读取)或“散布”(随机索引写入)。
  • 步长应该是单位步长。
注意

@simd 默认情况下不断言循环完全没有循环携带的内存依赖关系,这是一个在通用代码中很容易被违反的假设。如果您正在编写非通用代码,您可以使用 @simd ivdep for ... end 来断言

  • 不存在循环携带的内存依赖关系。
  • 没有迭代等待先前迭代以取得进展。
来源
Base.@polly
@polly

告诉编译器对函数应用多面体优化器 Polly。

来源
Base.@generated
@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"
来源
Base.@assume_effects
@assume_effects setting... [ex]

覆盖给定方法或外部调用的编译器效果建模。@assume_effects 可以应用在函数定义之前或函数体内部。它也可以应用在 @ccall 表达式之前。

Julia 1.8

使用 Base.@assume_effects 需要 Julia 1.8 版本。

示例

julia> Base.@assume_effects :terminates_locally function pow(x)
           # this :terminates_locally allows `pow` to be constant-folded
           res = 1
           1 < x < 20 || error("bad pow")
           while x > 1
               res *= x
               x -= 1
           end
           return res
       end
pow (generic function with 1 method)

julia> code_typed() do
           pow(12)
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return 479001600
) => Int64

julia> code_typed() do
           map((2,3,4)) do x
               # this :terminates_locally allows this anonymous function to be constant-folded
               Base.@assume_effects :terminates_locally
               res = 1
               1 < x < 20 || error("bad pow")
               while x > 1
                   res *= x
                   x -= 1
               end
               return res
           end
       end
1-element Vector{Any}:
 CodeInfo(
1 ─     return (2, 6, 24)
) => Tuple{Int64, Int64, Int64}

julia> Base.@assume_effects :total !:nothrow @ccall jl_type_intersection(Vector{Int}::Any, Vector{<:Integer}::Any)::Any
Vector{Int64} (alias for Array{Int64, 1})
Julia 1.10

在函数体内部使用需要至少 Julia 1.10 版本。

警告

不正确使用此宏会导致未定义行为(包括崩溃、错误答案或其他难以追踪的错误)。谨慎使用,并且只有在绝对必要时才作为最后手段使用。即使在这种情况下,您也应该尽一切努力来最小化效果断言的强度(例如,如果 :nothrow 足够,请不要使用 :total)。

通常,每个 setting 值都会对函数的行为进行断言,而不需要编译器证明这种行为确实是真实的。这些断言是在所有世界年龄中进行的。因此,建议限制使用可能在以后扩展以使假设失效的通用函数(这会导致未定义行为)。

支持以下 setting 值。

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :terminates_locally
  • :notaskstate
  • :inaccessiblememonly
  • :foldable
  • :可移除的
  • :总数

扩展帮助


:consistent

:consistent 设置断言对于相等 (===) 输入

  • 终止方式(返回值、异常、非终止)将始终相同。
  • 如果方法返回,结果将始终相等。
注意

特别地,这意味着该方法不得返回新分配的可变对象。多个可变对象的分配(即使内容相同)也不相等。

注意

:consistent 一致性断言是在世界年龄的基础上进行的。更正式地说,将 $fᵢ$ 写为 $f$ 在世界年龄 $i$ 中的评估,那么我们需要

\[∀ i, x, y: x ≡ y → fᵢ(x) ≡ fᵢ(y)\]

但是,对于两个世界年龄 $i$$j$,使得 $i ≠ j$,我们可能会有 $fᵢ(x) ≢ fⱼ(y)$

另一个含义是,:consistent 函数不得使其返回值依赖于堆的状态或任何其他对于给定世界年龄不是常量的全局状态。

注意

:consistent 一致性包括优化器执行的所有合法重写。例如,浮点数 fastmath 操作不被视为 :consistent,因为优化器可能会重写它们,导致输出不一致,即使对于相同的世界年龄也是如此(例如,因为一个在解释器中运行,而另一个被优化了)。

注意

:consistent 一致性断言目前包括断言该函数不会执行任何未定义的行为(对于任何输入)。请注意,未定义的行为在技术上可能会导致该函数违反其他效果断言(例如 :nothrow:effect_free),但我们没有对此进行建模,除了 :consistent 之外的所有效果都假设不存在未定义的行为。

注意

如果 :consistent 函数通过抛出异常而终止,该异常本身不需要满足上述相等性要求。


:effect_free

:effect_free 设置断言该方法没有外部语义上可见的副作用。以下是外部语义上可见的副作用的不完整列表

  • 更改全局变量的值。
  • 修改堆(例如数组或可变值),除非以下情况
  • 更改方法表(例如,通过调用 eval)
  • 文件/网络/等 I/O
  • 任务切换

但是,以下内容明确地不是语义上可见的,即使它们可能是可观察的

  • 内存分配(可变和不可变)
  • 经过的时间
  • 垃圾收集
  • 堆对寿命不超过方法的对象的修改(即在方法中分配且没有转义的对象)。
  • 返回值(它是外部可见的,但不是副作用)

这里经验法则是,外部可见的副作用是任何会影响程序其余部分执行的内容,如果该函数没有执行。

注意

:effect_free 断言针对方法本身以及方法执行的任何代码都成立。请记住,该断言必须对所有世界年龄有效,并相应地限制该断言的使用。


:nothrow

:nothrow 设置断言该方法不会异常终止(即始终返回一个值或从不返回)。

注意

允许 :nothrow 注释方法在内部使用异常处理,只要异常没有被重新抛出方法本身之外即可。

注意

MethodErrors 和类似的异常被视为异常终止。


:terminates_globally

:terminates_globally 设置断言该方法最终会终止(正常或异常),即不会无限循环。

注意

:terminates_globally 断言涵盖注释方法调用的任何其他方法。

注意

编译器将认为这是一个强烈的迹象,表明该方法将相对快速地终止,并且可能(如果在法律允许的情况下)在编译时调用该方法。也就是说,对一个技术上但不是实际上终止的方法注释此设置是一个不好的做法。


:terminates_locally

:terminates_locally 设置类似于 :terminates_globally,只是它只适用于注释方法内部的语法控制流。因此,这是一个更弱(因此更安全)的断言,允许在方法调用某些不终止的其他方法的情况下,可能出现非终止。

注意

:terminates_globally 意味着 :terminates_locally


:notaskstate

:notaskstate 设置断言该方法不使用或修改本地任务状态(任务本地存储、RNG 状态等),因此可以在任务之间安全地移动,而不会产生可观察的结果。

注意

异常处理的实现使用存储在任务对象中的状态。但是,此状态目前不被认为在 :notaskstate 的范围内,并使用 :nothrow 效果单独跟踪。

注意

:notaskstate 断言关注当前正在运行的任务的状态。如果通过某种不考虑当前正在运行的任务的方法获得对 Task 对象的引用,则 :notaskstate 效果不需要被污染。即使所述任务对象恰好与当前正在运行的任务相同,也是如此。

注意

访问任务状态通常也会导致其他效果的污染,例如 :effect_free(如果修改了任务状态)或 :consistent(如果在计算结果时使用了任务状态)。特别是,不是 :notaskstate 但却是 :effect_free:consistent 的代码仍然可以进行死代码消除,因此可以提升为 :total


:inaccessiblememonly

:inaccessiblememonly 设置断言该方法不访问或修改外部可访问的可变内存。这意味着该方法可以访问或修改新分配对象的可变内存,该内存不可由其他方法或方法返回之前进行的顶层执行访问,但它不能访问或修改任何可变全局状态或其参数指向的可变内存。

注意

以下是使此假设失效的示例的不完整列表

  • 访问可变全局变量的全局引用或 getglobal 调用
  • 对非常量全局变量进行赋值的全局赋值或 setglobal! 调用
  • 更改全局可变变量字段的 setfield! 调用
注意

:inaccessiblememonly 断言涵盖注释方法调用的任何其他方法。


:foldable

此设置是编译器需要保证在编译时进行常量折叠的一组效果的便捷捷径。它目前等效于以下 设置

  • :consistent
  • :effect_free
  • :terminates_globally
注意

此列表尤其不包括 :nothrow。编译器仍将尝试进行常量传播并在编译时记录任何抛出的错误。但是请注意,根据 :consistent 一致性要求,任何这样的注释调用在给定相同的参数值的情况下必须始终抛出。

注意

函数内部的显式 @inbounds 注释也将禁用常量折叠,并且不会被 :foldable 覆盖。


:可移除的

此设置是编译器需要保证在编译时删除其结果在编译时未使用的调用的效果集的便捷捷径。它目前等效于以下 设置

  • :effect_free
  • :nothrow
  • :terminates_globally

:总数

设置 是最大的可能的设置集。它目前意味着以下其他 设置

  • :consistent
  • :effect_free
  • :nothrow
  • :terminates_globally
  • :notaskstate
  • :inaccessiblememonly
警告

:total 是一个非常强的断言,并且可能会在 Julia 的未来版本中获得额外的语义(例如,如果添加了额外的效果并包含在 :total 的定义中)。因此,应该谨慎使用。只要有可能,最好使用特定应用程序所需的最小可能的特定效果断言集。在大量效果覆盖应用于一组函数的情况下,建议使用自定义宏而不是 :total


否定效果

效果名称可以以 ! 为前缀,表示应从更早的元效果中删除该效果。例如,:total !:nothrow 表示虽然调用通常是完整的,但它可能抛出异常。

来源
Base.@deprecate
@deprecate old new [export_old=true]

弃用方法 old 并指定替换调用 new,在此过程中定义一个具有指定签名的新的方法 old

要防止 old 被导出,将 export_old 设置为 false

Julia 1.5

从 Julia 1.5 开始,由 @deprecate 定义的函数在没有设置 --depwarn=yes 标志的情况下运行 julia 时不会打印警告,因为 --depwarn 选项的默认值为 no。警告是从 Pkg.test() 运行的测试中打印的。

示例

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 的位置和关键字参数的已弃用方法。

Julia 1.9

从 Julia 1.9 开始,在没有显式类型注释的情况下,关键字参数会被转发。对于旧版本,您可以通过执行 @deprecate old(args...; kwargs...) new(args...; kwargs...) 来手动转发位置和关键字参数。

要将弃用限制为特定签名,请注释 old 的参数。例如,

julia> new(x::Int) = x;

julia> new(x::Float64) = 2x;

julia> @deprecate old(x::Int) new(x);

julia> methods(old)
# 1 method for generic function "old" from Main:
 [1] old(x::Int64)
     @ deprecated.jl:94

将定义并弃用一个方法 old(x::Int),它镜像 new(x::Int),但不会定义或弃用方法 old(x::Float64)

来源

缺失值

Base.coalesce函数
coalesce(x...)

返回参数中第一个不等于 missing 的值(如果有)。否则返回 missing

另请参见 skipmissingsomething@coalesce

示例

julia> coalesce(missing, 1)
1

julia> coalesce(1, missing)
1

julia> coalesce(nothing, 1)  # returns `nothing`

julia> coalesce(missing, missing)
missing
来源
Base.@coalesce
@coalesce(x...)

coalesce 的短路版本。

示例

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
[...]
Julia 1.7

此宏从 Julia 1.7 开始可用。

来源
Base.skipmissing函数
skipmissing(itr)

返回一个迭代器,遍历 itr 中的元素,跳过 missing 值。如果 itr 是可索引的,则返回的对象可以使用 itr 的索引进行索引。对应于缺失值的索引无效:它们被 keyseachindex 跳过,并且在尝试使用它们时会抛出 MissingException

使用 collect 获取一个包含 itr 中非 missing 值的 Array。请注意,即使 itr 是一个多维数组,结果也将始终是一个 Vector,因为在保留输入的维度的情况下无法删除缺失值。

另请参见 coalesceismissingsomething

示例

julia> x = skipmissing([1, missing, 2])
skipmissing(Union{Missing, Int64}[1, missing, 2])

julia> sum(x)
3

julia> x[1]
1

julia> x[2]
ERROR: MissingException: the value at index (2,) is missing
[...]

julia> argmax(x)
3

julia> collect(keys(x))
2-element Vector{Int64}:
 1
 3

julia> collect(skipmissing([1, missing, 2]))
2-element Vector{Int64}:
 1
 2

julia> collect(skipmissing([1 missing; 2 missing]))
2-element Vector{Int64}:
 1
 2
来源
Base.nonmissingtype函数
nonmissingtype(T::Type)

如果 T 是包含 Missing 的类型的联合,则返回一个删除了 Missing 的新类型。

示例

julia> nonmissingtype(Union{Int64,Missing})
Int64

julia> nonmissingtype(Any)
Any
Julia 1.3

此函数从 Julia 1.3 版本开始导出。

来源

系统

Base.run函数
run(command, args...; wait::Bool = true)

运行一个命令对象,该对象是用反引号构建的(参见手册中的运行外部程序部分)。如果出现任何错误,包括进程以非零状态退出(当 wait 为真时),则抛出错误。

args... 允许您将文件描述符传递给命令,并且它们的顺序与常规的 Unix 文件描述符相同(例如 stdin, stdout, stderr, FD(3), FD(4)...)。

如果 wait 为假,则进程异步运行。您可以稍后等待它并通过调用返回的进程对象的 success 来检查其退出状态。

wait 为假时,进程的 I/O 流将定向到 devnull。当 wait 为真时,I/O 流将与父进程共享。使用 pipeline 来控制 I/O 重定向。

来源
Base.devnull常量
devnull

在流重定向中使用,以丢弃写入它的所有数据。本质上等同于 Unix 上的 /dev/null 或 Windows 上的 NUL。用法

run(pipeline(`cat test.txt`, devnull))
来源
Base.success函数
success(command)

运行一个命令对象,该对象是用反引号构建的(参见手册中的运行外部程序部分),并判断它是否成功(以 0 代码退出)。如果进程无法启动,则会引发异常。

来源
Base.kill方法
kill(p::Process, signum=Base.SIGTERM)

向一个进程发送信号。默认情况下,将终止进程。如果进程已退出,则返回成功,但如果由于其他原因(例如权限不足)而无法杀死进程,则抛出错误。

来源
Base.ignorestatus函数
ignorestatus(command)

标记一个命令对象,以便运行它时,如果结果代码不为零,不会抛出错误。

来源
Base.detach函数
detach(command)

标记一个命令对象,以便它将在新的进程组中运行,允许它比 Julia 进程存活更久,并且不会将 Ctrl-C 中断传递给它。

来源
Base.Cmd类型
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)
来源
Base.setenv函数
setenv(command::Cmd, env; dir)

设置在运行给定 command 时使用的环境变量。env 可以是字典(将字符串映射到字符串)、字符串数组(形式为 "var=val")、零个或多个 "var"=>val 键值对参数。为了修改(而不是替换)现有环境,请通过 copy(ENV) 创建 env,然后设置 env["var"]=val,或者使用 addenv

dir 关键字参数可用于指定命令的工作目录。dir 默认为 command 当前设置的 dir(如果未指定,则为当前工作目录)。

另见 CmdaddenvENVpwd

来源
Base.addenv函数
addenv(command::Cmd, env...; inherit::Bool = true)

将新的环境映射合并到给定的 Cmd 对象中,返回一个新的 Cmd 对象。重复的键将被替换。如果 command 不包含任何已设置的环境值,则如果 inherittrue,它将继承 addenv() 调用时的当前环境。值为 nothing 的键将从 env 中删除。

另见 CmdsetenvENV

Julia 1.6

此函数需要 Julia 1.6 或更高版本。

来源
Base.withenv函数
withenv(f, kv::Pair...)

在环境中执行 f,该环境被零个或多个 "var"=>val 参数 kv 临时修改(而不是替换,如 setenv 中所做)。withenv 通常通过 withenv(kv...) do ... end 语法使用。nothing 值可用于临时取消设置环境变量(如果已设置)。当 withenv 返回时,原始环境已恢复。

警告

更改环境不是线程安全的。对于使用与父进程不同的环境运行外部命令,建议使用 addenv 而不是 withenv

来源
Base.setcpuaffinity函数
setcpuaffinity(original_command::Cmd, cpus) -> command::Cmd

通过 CPU ID 列表(从 1 开始)cpus 设置 command 的 CPU 亲和性。传递 cpus = nothing 表示如果 original_command 有任何亲和性设置,则取消设置 CPU 亲和性。

此函数仅在 Linux 和 Windows 中受支持。它在 macOS 中不受支持,因为 libuv 不支持亲和性设置。

Julia 1.8

此函数至少需要 Julia 1.8。

示例

在 Linux 中,可以使用 taskset 命令行程序来查看 setcpuaffinity 的工作原理。

julia> run(setcpuaffinity(`sh -c 'taskset -p $$'`, [1, 2, 5]));
pid 2273's current affinity mask: 13

请注意,掩码值 13 反映了第一个、第二个和第五个位(从最低有效位置开始计数)被打开

julia> 0b010011
0x13
来源
Base.pipeline方法
pipeline(from, to, ...)

从数据源创建到目的地的管道。源和目的地可以是命令、I/O 流、字符串或其他 pipeline 调用的结果。至少有一个参数必须是命令。字符串指的是文件名。当使用两个以上参数调用时,它们将从左到右链接在一起。例如,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`))
来源
Base.pipeline方法
pipeline(command; stdin, stdout, stderr, append=false)

将 I/O 重定向到或从给定的 command 中。关键字参数指定命令的哪些流应该被重定向。append 控制文件输出是否追加到文件。这是一个更通用的 2 参数 pipeline 函数版本。pipeline(from, to) 等同于 pipeline(from, stdout=to)(当 from 是命令时),以及 pipeline(to, stdin=from)(当 from 是其他类型的数据源时)。

示例:

run(pipeline(`dothings`, stdout="out.txt", stderr="errs.txt"))
run(pipeline(`update`, stdout="log.txt", append=true))
来源
Base.Libc.getpid函数
getpid() -> Int32

获取 Julia 的进程 ID。

来源
getpid(process) -> Int32

获取子进程 ID(如果它仍然存在)。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

来源
Base.Libc.time方法
time() -> Float64

获取自纪元以来的系统时间(以秒为单位),具有相当高的(通常是微秒级)分辨率。

来源
Base.time_ns函数
time_ns() -> UInt64

获取以纳秒为单位的时间。对应于 0 的时间未定义,并且每 5.8 年循环一次。

来源
Base.@time
@time expr
@time "description" expr

一个宏,用于执行表达式,在返回表达式的值之前,打印执行该表达式所花费的时间、分配的数量以及其执行导致分配的总字节数。任何花费在垃圾回收 (gc)、编译新代码或重新编译失效代码上的时间都将显示为百分比。

可以选择提供一个描述字符串,在时间报告之前打印。

在某些情况下,系统将查看 @time 表达式内部,并在顶层表达式开始执行之前编译一些被调用的代码。发生这种情况时,一些编译时间将不会被计算。要包含此时间,您可以运行 @time @eval ...

另见 @showtime@timev@timed@elapsed@allocated 以及 @allocations

注意

对于更严肃的基准测试,请考虑 BenchmarkTools.jl 包中的 @btime 宏,该宏除其他事项外,会多次评估函数以减少噪声。

Julia 1.8

在 Julia 1.8 中引入了添加描述的选项。

在 Julia 1.8 中引入了将重新编译时间与编译时间分开显示的功能。

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)
来源
Base.@showtime
@showtime expr

类似于 @time,但还会打印被计算的表达式以供参考。

Julia 1.8

此宏是在 Julia 1.8 中添加的。

另请参阅 @time.

julia> @showtime sleep(1)
sleep(1): 1.002164 seconds (4 allocations: 128 bytes)
来源
Base.@timev
@timev expr
@timev "description" expr

这是 @time 宏的详细版本。它首先打印与 @time 相同的信息,然后打印任何非零内存分配计数器,最后返回表达式的值。

可以选择提供一个描述字符串,在时间报告之前打印。

Julia 1.8

在 Julia 1.8 中引入了添加描述的选项。

另请参阅 @time@timed@elapsed@allocated@allocations.

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
来源
Base.@timed
@timed

一个宏,用于执行表达式并返回表达式的值、经过时间、分配的总字节数、垃圾收集时间以及一个包含各种内存分配计数器的对象。

在某些情况下,系统会查看 @timed 表达式内部,并在执行顶层表达式之前编译部分调用的代码。发生这种情况时,一些编译时间将不会被计算在内。要包含此时间,您可以运行 @timed @eval ...

另请参阅 @time@timev@elapsed@allocated@allocations.

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 1.5

此宏的返回值类型在 Julia 1.5 中从 Tuple 更改为 NamedTuple

来源
Base.@elapsed
@elapsed

一个宏,用于计算表达式,丢弃结果值,而是返回执行所需时间的秒数,以浮点数形式表示。

在某些情况下,系统会查看 @elapsed 表达式内部,并在执行顶层表达式之前编译部分调用的代码。发生这种情况时,一些编译时间将不会被计算在内。要包含此时间,您可以运行 @elapsed @eval ...

另请参阅 @time@timev@timed@allocated@allocations.

julia> @elapsed sleep(0.3)
0.301391426
来源
Base.@allocations
@allocations

一个宏,用于计算表达式,丢弃结果值,而是返回在计算表达式期间的总分配次数。

另请参阅 @allocated@time@timev@timed@elapsed.

julia> @allocations rand(10^6)
2
Julia 1.9

此宏是在 Julia 1.9 中添加的。

来源
Base.EnvDict类型
EnvDict() -> EnvDict

此类型的单例提供了对环境变量的哈希表接口。

来源
Base.ENV常量
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"

另请参阅:withenvaddenv.

来源
Base.Sys.STDLIB常量
Sys.STDLIB::String

一个字符串,包含包含 stdlib 包的目录的完整路径。

来源
Base.Sys.isbsd函数
Sys.isbsd([os])

用于测试操作系统是否为 BSD 的派生版本。请参阅 处理操作系统差异 中的文档。

注意

Darwin 内核源于 BSD,这意味着 Sys.isbsd() 在 macOS 系统上为 true。要从谓词中排除 macOS,请使用 Sys.isbsd() && !Sys.isapple()

来源
Base.Sys.isfreebsd函数
Sys.isfreebsd([os])

用于测试操作系统是否为 FreeBSD 的派生版本。请参阅 处理操作系统差异 中的文档。

注意

不要与 Sys.isbsd() 混淆,后者在 FreeBSD 上为 true,但在其他基于 BSD 的系统上也为 trueSys.isfreebsd() 仅指 FreeBSD。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

来源
Base.Sys.isopenbsd函数
Sys.isopenbsd([os])

用于测试操作系统是否为 OpenBSD 的派生版本。请参阅 处理操作系统差异 中的文档。

注意

不要与 Sys.isbsd() 混淆,后者在 OpenBSD 上为 true,但在其他基于 BSD 的系统上也为 trueSys.isopenbsd() 仅指 OpenBSD。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

来源
Base.Sys.isnetbsd函数
Sys.isnetbsd([os])

用于测试操作系统是否为 NetBSD 的派生版本。请参阅 处理操作系统差异 中的文档。

注意

不要与 Sys.isbsd() 混淆,后者在 NetBSD 上为 true,但在其他基于 BSD 的系统上也为 trueSys.isnetbsd() 仅指 NetBSD。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

来源
Base.Sys.isdragonfly函数
Sys.isdragonfly([os])

用于测试操作系统是否为 DragonFly BSD 的派生版本。请参阅 处理操作系统差异 中的文档。

注意

不要与 Sys.isbsd() 混淆,后者在 DragonFly 上为 true,但在其他基于 BSD 的系统上也为 trueSys.isdragonfly() 仅指 DragonFly。

Julia 1.1

该函数需要至少 Julia 1.1 版本。

来源
Base.Sys.windows_version函数
Sys.windows_version()

将 Windows NT 内核的版本号返回为 VersionNumber,即 v"major.minor.build",或者如果不在 Windows 上运行,则返回 v"0.0.0"

来源
Base.Sys.total_memory函数
Sys.total_memory()

获取 RAM 中的总内存(包括当前使用的内存),以字节为单位。此数量可能受到限制,例如,受到 Linux 控制组的限制。对于不受约束的数量,请参阅 Sys.total_physical_memory()

来源
Base.Sys.free_physical_memory函数
Sys.free_physical_memory()

获取系统的空闲内存(以字节为单位)。整个数量可能无法提供给当前进程;使用 Sys.free_memory() 获取实际可用的数量。

来源
Base.Sys.total_physical_memory函数
Sys.total_physical_memory()

获取 RAM 中的总内存(包括当前使用的内存),以字节为单位。整个数量可能无法提供给当前进程;请参阅 Sys.total_memory()

来源
Base.Sys.isjsvm函数
Sys.isjsvm([os])

用于测试 Julia 是否在 JavaScript VM (JSVM) 中运行的谓词,包括例如 WebAssembly JavaScript 在网页浏览器中的嵌入。

Julia 1.2

此函数至少需要 Julia 1.2。

来源
Base.Sys.loadavg函数
Sys.loadavg()

获取负载平均值。请参阅:https://en.wikipedia.org/wiki/Load_(computing)。

来源
Base.Sys.isexecutable函数
Sys.isexecutable(path::String)

如果给定的 path 具有可执行权限,则返回 true

注意

在 Julia 1.6 之前,此方法无法在 Windows 上正确查询文件系统 ACL,因此它会对任何文件返回 true。从 Julia 1.6 开始,它会正确判断文件是否被标记为可执行文件。

来源
Base.@static
@static

在解析时部分计算表达式。

例如,@static Sys.iswindows() ? foo : bar 将计算 Sys.iswindows() 并将 foobar 插入表达式中。这在某些情况下很有用,例如在其他平台上无效的结构,例如对不存在的函数的 ccall@static if Sys.isapple() foo end@static foo <&&,||> bar 也是有效的语法。

来源

版本控制

Base.VersionNumber类型
VersionNumber

版本号类型,遵循 语义版本控制 (semver) 的规范,由主版本、次版本和修订版本数字组成,后面跟着预发布和构建的字母数字注释。

VersionNumber 对象可以使用所有标准比较运算符(==<<= 等)进行比较,结果遵循 semver 规则。

另请参见 @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
来源
Base.@v_str
@v_str

用于将字符串解析为 VersionNumber 的字符串宏。

示例

julia> v"1.2.3"
v"1.2.3"

julia> v"2.0.1-rc1"
v"2.0.1-rc1"
来源

错误

Base.error函数
error(message::AbstractString)

使用给定消息引发 ErrorException

来源
error(msg...)

使用给定消息引发 ErrorException

来源
Base.rethrow函数
rethrow()

catch 块中重新抛出当前异常。重新抛出的异常将继续传播,就像它没有被捕获一样。

注意

备用形式 rethrow(e) 允许您将备用异常对象 e 与当前回溯相关联。但是,这会错误地表示错误发生时的程序状态,因此建议您改为使用 throw(e) 抛出新异常。在 Julia 1.1 及更高版本中,使用 throw(e) 将保留堆栈上的根本原因异常,如 current_exceptions 中所述。

来源
Base.current_exceptions函数
current_exceptions(task::Task=current_task(); [backtrace::Bool=true])

获取当前正在处理的异常堆栈。对于嵌套的 catch 块,可能存在多个当前异常,在这种情况下,最近抛出的异常位于堆栈的最后。堆栈作为 ExceptionStack 返回,它是一个包含命名元组 (exception,backtrace) 的 AbstractVector。如果 backtrace 为 false,则每对中的回溯将设置为 nothing

显式传递 task 将返回任意任务上的当前异常堆栈。这对于检查由于未捕获异常而导致失败的任务很有用。

Julia 1.7

此函数在 Julia 1.1–1.6 中使用实验名称 catch_stack(),并具有作为返回类型的普通 Vector-of-tuples。

来源
Base.@assert
@assert cond [text]

如果 condfalse,则抛出 AssertionError。编写断言的首选语法。消息 text 可选地显示在断言失败时。

警告

断言可能会在不同的优化级别被禁用。因此,断言应该只用作调试工具,不应用于身份验证验证(例如,验证密码),也不应在断言内部使用函数正常工作所需的副作用。

示例

julia> @assert iseven(3) "3 is an odd number!"
ERROR: AssertionError: 3 is an odd number!

julia> @assert isodd(3) "What even are numbers?"
来源
Base.Experimental.register_error_hint函数
Experimental.register_error_hint(handler, exceptiontype)

注册一个“提示”函数 handler(io, exception),该函数可以建议用户规避错误的潜在方法。handler 应该检查 exception 以查看是否满足提示的条件,如果满足,则向 io 生成输出。包应该从其 __init__ 函数中调用 register_error_hint

对于特定异常类型,handler 需要接受附加参数

  • MethodError:提供 handler(io, exc::MethodError, argtypes, kwargs),它将组合参数拆分为位置参数和关键字参数。

在发出提示时,输出通常应该以 \n 开头。

如果您定义自定义异常类型,则您的 showerror 方法可以通过调用 Experimental.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
                    # Color is not necessary, this is just to show it's possible.
                    print(io, "\nDid you mean to call ")
                    printstyled(io, "`any_number`?", color=:cyan)
               end
           end
       end

       end

然后,如果您在不是 Int 的内容上调用 Hinter.only_int(从而触发 MethodError),它会发出提示

julia> Hinter.only_int(1.0)
ERROR: MethodError: no method matching only_int(::Float64)
Did you mean to call `any_number`?
Closest candidates are:
    ...
Julia 1.5

自定义错误提示从 Julia 1.5 开始可用。

警告

此接口是实验性的,可能会在未经通知的情况下更改或删除。为了避免更改,请考虑将任何注册放在 if isdefined(Base.Experimental, :register_error_hint) ... end 块中。

来源
Base.Experimental.show_error_hints函数
Experimental.show_error_hints(io, ex, args...)

为特定异常类型 typeof(ex) 调用 Experimental.register_error_hint 中的所有处理程序。args 必须包含该类型处理程序期望的任何其他参数。

Julia 1.5

自定义错误提示从 Julia 1.5 开始可用。

警告

此接口是实验性的,可能会在未经通知的情况下更改或删除。

来源
Core.ArgumentError类型
ArgumentError(msg)

传递给函数的参数无效。msg 是一个描述性的错误消息。

来源
Core.AssertionError类型
AssertionError([msg])

断言的条件没有计算为 true。可选参数 msg 是一个描述性的错误字符串。

示例

julia> @assert false "this is not true"
ERROR: AssertionError: this is not true

AssertionError 通常由 @assert 抛出。

来源
Core.BoundsError类型
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]
来源
Base.CompositeException类型
CompositeException

使用有关异常系列的信息包装由 Task 抛出的异常 Vector(例如,从通道上的远程工作器、异步执行的本地 I/O 写入或 pmap 下的远程工作器生成)。例如,如果一群工作器正在执行多个任务,而多个工作器失败,则生成的 CompositeException 将包含来自每个工作器的“捆绑”信息,指示异常发生的位置和原因。

来源
Base.DimensionMismatch类型
DimensionMismatch([msg])

调用的对象没有匹配的维度。可选参数 msg 是一个描述性的错误字符串。

来源
Core.DivideError类型
DivideError()

整数除法尝试使用值为 0 的除数。

示例

julia> 2/0
Inf

julia> div(2, 0)
ERROR: DivideError: integer division error
Stacktrace:
[...]
来源
Core.DomainError类型
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:
[...]
来源
Core.ErrorException类型
ErrorException(msg)

通用错误类型。.msg 字段中的错误消息可能提供更具体的详细信息。

示例

julia> ex = ErrorException("I've done a bad thing");

julia> ex.msg
"I've done a bad thing"
来源
Core.InexactError类型
InexactError(name::Symbol, T, val)

无法将 val 精确转换为函数 name 方法中的类型 T

示例

julia> convert(Float64, 1+2im)
ERROR: InexactError: Float64(1 + 2im)
Stacktrace:
[...]
来源
Core.InterruptException类型
InterruptException()

该进程被终端中断(CTRL+C)停止。

请注意,在没有 -i(交互式)选项的情况下启动的 Julia 脚本中,默认情况下不会抛出 InterruptException。在脚本中调用 Base.exit_on_sigint(false) 可以恢复 REPL 的行为。或者,可以使用以下方法启动 Julia 脚本:

julia -e "include(popfirst!(ARGS))" script.jl

以允许 InterruptException 在执行期间被 CTRL+C 抛出。

来源
Base.KeyError类型
KeyError(key)

AbstractDict (Dict) 或类似 Set 对象的索引操作尝试访问或删除不存在的元素。

来源
Core.LoadError类型
LoadError(file::AbstractString, line::Int, error)

includerequireusing 文件时发生错误。错误细节应该在 .error 字段中可用。

Julia 1.7

从 Julia 1.7 开始,@macroexpand@macroexpand1macroexpand 不再发出 LoadErrors。

来源
Core.MethodError类型
MethodError(f, args)

在给定泛型函数中不存在具有所需类型签名的方法。或者,不存在唯一的、最具体的、最通用的方法。

来源
Base.MissingException类型
MissingException(msg)

当在不支持 missing 值的情况下遇到它时,抛出异常。msg 字段中的错误消息可能提供更具体的详细信息。

来源
Core.OutOfMemoryError类型
OutOfMemoryError()

操作分配的内存过多,以至于系统或垃圾收集器无法正确处理。

来源
Core.OverflowError类型
OverflowError(msg)

表达式的结果对于指定的类型来说太大,会导致回绕。

来源
Base.ProcessFailedException类型
ProcessFailedException

表示进程退出状态有问题。在运行命令或管道时,抛出此异常以指示返回了非零退出代码(即调用的进程失败)。

来源
Core.StackOverflowError类型
StackOverflowError()

函数调用超出了调用堆栈的大小。这通常发生在调用无限递归时。

来源
Base.SystemError类型
SystemError(prefix::AbstractString, [errno::Int32])

系统调用失败并返回错误代码(在 errno 全局变量中)。

来源
Core.TypeError类型
TypeError(func::Symbol, context::AbstractString, expected::Type, got)

类型断言失败,或使用不正确的参数类型调用内在函数。

来源
Core.UndefKeywordError类型
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
来源
Core.UndefRefError类型
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:
[...]
来源
Core.UndefVarError类型
UndefVarError(var::Symbol)

当前作用域中未定义符号。

示例

julia> a
ERROR: UndefVarError: `a` not defined

julia> a = 1;

julia> a
1
来源
Core.InitError类型
InitError(mod::Symbol, error)

在运行模块的__init__函数时发生了错误。实际抛出的错误可在.error字段中找到。

来源
Base.retry函数
retry(f;  delays=ExponentialBackOff(), check=nothing) -> Function

返回一个匿名函数,该函数调用函数f。如果出现异常,f会反复调用,每次check返回true时,在等待delays中指定的秒数后进行调用。check应输入delays的当前状态和Exception

Julia 1.2

在 Julia 1.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)
来源
Base.ExponentialBackOff类型
ExponentialBackOff(; n=1, first_delay=0.05, max_delay=10.0, factor=5.0, jitter=0.1)

一个长度为nFloat64迭代器,其元素以factor * (1 ± jitter) 的速率呈指数增长。第一个元素是first_delay,所有元素都被限制为max_delay

来源

事件

Base.Timer方法
Timer(callback::Function, delay; interval = 0)

创建一个定时器,在每次定时器到期时运行函数callback

等待的任务会在初始延迟delay秒后被唤醒,函数callback会被调用,然后以给定的interval秒为间隔重复调用。如果interval等于0,则callback只运行一次。函数callback使用单个参数调用,即定时器本身。通过调用close停止定时器。如果定时器已经到期,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
来源
Base.Timer类型
Timer(delay; interval = 0)

创建一个定时器,唤醒等待它的任务(通过对定时器对象调用wait)。

等待的任务会在至少delay秒的初始延迟后被唤醒,然后在至少interval秒后再次被唤醒。如果interval等于0,则定时器只触发一次。当定时器关闭(通过close)时,等待的任务会被唤醒并出现错误。使用isopen检查定时器是否仍然处于活动状态。

注意

interval会受到累积时间偏差的影响。如果你需要在特定的绝对时间进行精确的事件,请在每次到期时创建一个新的定时器,并计算到下次时间的差值。

注意

Timer需要让步点来更新其状态。例如,isopen(t::Timer)不能用于超时一个不产生让步的 while 循环。

来源
Base.AsyncCondition类型
AsyncCondition()

创建一个异步条件,当通过调用uv_async_send从 C 中收到通知时,会唤醒等待它的任务(通过对对象调用wait)。当对象关闭(通过close)时,等待的任务会被唤醒并出现错误。使用isopen检查它是否仍然处于活动状态。

这在发送线程和等待线程之间提供了一个隐式的获取和释放内存排序。

来源
Base.AsyncCondition方法
AsyncCondition(callback::Function)

创建一个异步条件,调用给定的callback函数。callback传递一个参数,即异步条件对象本身。

来源

反射

Base.nameof方法
nameof(m::Module) -> Symbol

获取Module的名称,作为Symbol

示例

julia> nameof(Base.Broadcast)
:Broadcast
来源
Base.parentmodule函数
parentmodule(m::Module) -> Module

获取模块的封闭ModuleMain是它自己的父模块。

另请参阅:namesnameoffullname@__MODULE__.

示例

julia> parentmodule(Main)
Main

julia> parentmodule(Base.Broadcast)
Base
来源
parentmodule(t::DataType) -> Module

确定包含(可能被UnionAll包装的)DataType定义的模块。

示例

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的模块。

Julia 1.9

Method作为参数传递需要 Julia 1.9 或更高版本。

来源
Base.pathof方法
pathof(m::Module)

返回用于import模块mm.jl文件的路径,如果m不是从包中导入的,则返回nothing

使用dirname获取路径的目录部分,并使用basename获取路径的文件名部分。

来源
Base.pkgdir方法
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"
Julia 1.7

可选参数paths需要 Julia 1.7 或更高版本。

来源
Base.pkgversion方法
pkgversion(m::Module)

返回导入模块m的包的版本,如果m不是从包中导入的,或者从没有设置版本字段的包中导入的,则返回nothing

版本是在包加载期间从包的 Project.toml 中读取的。

要获取导入当前模块的包的版本,可以使用pkgversion(@__MODULE__)的形式。

Julia 1.9

此函数在 Julia 1.9 中引入。

来源
Base.moduleroot函数
moduleroot(m::Module) -> Module

查找给定模块的根模块。这是m的父模块链中的第一个模块,它要么是已注册的根模块,要么是它自己的父模块。

来源
__module__关键字
__module__

参数__module__仅在宏内部可见,它提供有关宏调用扩展上下文的信息(以Module对象的形式)。有关更多信息,请参阅有关宏调用的手册部分。

来源
__source__关键字
__source__

参数__source__仅在宏内部可见,它提供有关宏调用中@符号的解析器位置的信息(以LineNumberNode对象的形式)。有关更多信息,请参阅有关宏调用的手册部分。

来源
Base.@__MODULE__
@__MODULE__ -> Module

获取顶层评估的Module,即当前正在从中读取代码的Module

来源
Base.@__FILE__
@__FILE__ -> String

扩展为包含宏调用的文件的路径的字符串,如果通过julia -e <expr>评估,则为一个空字符串。如果宏缺少解析器源信息,则返回nothing。或者请参阅PROGRAM_FILE

来源
Base.@__DIR__
@__DIR__ -> String

扩展为包含宏调用的文件的目录的绝对路径的字符串。如果从 REPL 运行或通过julia -e <expr>评估,则返回当前工作目录。

来源
Base.@__LINE__
@__LINE__ -> Int

扩展为宏调用的位置的行号。如果无法确定行号,则返回0

来源
Base.fullname函数
fullname(m::Module)

获取模块的完全限定名称,作为符号元组。例如,

示例

julia> fullname(Base.Iterators)
(:Base, :Iterators)

julia> fullname(Main)
(:Main,)
来源
Base.names函数
names(x::Module; all::Bool = false, imported::Bool = false)

获取Module导出的名称数组,不包括弃用名称。如果all为真,则列表还包括模块中定义的非导出名称、弃用名称和编译器生成的名称。如果imported为真,则还包括显式从其他模块导入的名称。

作为特殊情况,Main中定义的所有名称都被认为是“导出的”,因为在Main中显式导出名称是不符合习惯的。

另请参阅:@locals@__MODULE__.

来源
Base.nameof方法
nameof(f::Function) -> Symbol

获取泛型Function的名称,作为符号。对于匿名函数,这是一个编译器生成的名称。对于显式声明的Function子类型,它是函数类型的名称。

来源
Base.functionloc方法
functionloc(f::Function, types)

返回一个元组(filename,line),给出泛型Function定义的位置。

来源
Base.functionloc方法
functionloc(m::Method)

返回一个元组(filename,line),给出Method定义的位置。

来源
Base.@locals
@locals()

构造一个字典,包含调用点定义的所有局部变量的名称(作为符号)和值。

Julia 1.1

此宏需要 Julia 1.1 或更高版本。

示例

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)
来源

代码加载

Base.identify_package函数
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 is a dependency of the default environment
Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f]

julia> using LinearAlgebra

julia> Base.identify_package(LinearAlgebra, "Pkg") # Pkg is not a dependency of LinearAlgebra
来源
Base.locate_package函数
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.10/Pkg/src/Pkg.jl"
来源
Base.require函数
require(into::Module, module::Symbol)

此函数是using / import实现的一部分,如果Main中尚未定义模块。它也可以直接调用,以强制重新加载模块,而不管它之前是否加载过(例如,在交互式开发库时)。

在每个活动节点上加载源文件,在 Main 模块的上下文中,在标准位置搜索文件。require 被认为是顶级操作,因此它设置当前的 include 路径,但不会使用它来搜索文件(有关 include 的帮助,请参阅帮助)。此函数通常用于加载库代码,并且由 using 隐式调用来加载包。

在搜索文件时,require 首先在全局数组 LOAD_PATH 中查找包代码。require 对所有平台上的文件名大小写敏感,包括 macOS 和 Windows 等具有不区分大小写文件系统的平台。

有关代码加载的更多详细信息,请参阅手册中关于 模块并行计算 的部分。

来源
Base.compilecache函数
Base.compilecache(module::PkgId)

为模块及其所有依赖项创建预编译的缓存文件。这可以用于减少包加载时间。缓存文件存储在 DEPOT_PATH[1]/compiled 中。有关重要说明,请参阅 模块初始化和预编译

来源
Base.isprecompiled函数
Base.isprecompiled(pkg::PkgId; ignore_loaded::Bool=false)

返回活动项目中给定 PkgId 是否已预编译。

默认情况下,此检查遵循与代码加载相同的方案,即当前加载的依赖项的不同版本与预期版本相对应。要忽略已加载的模块并像在新的 julia 会话中一样回答,请指定 ignore_loaded=true

Julia 1.10

此函数至少需要 Julia 1.10。

来源
Base.get_extension函数
get_extension(parent::Module, extension::Symbol)

返回 parentextension 模块,如果扩展未加载,则返回 nothing

来源

内部机制

Base.GC.gc函数
GC.gc([full=true])

执行垃圾回收。参数 full 决定回收的类型:完全回收(默认)会清除所有对象,这会使下次 GC 扫描速度变慢,而增量回收可能只清除所谓的年轻对象。

警告

过度使用可能会导致性能下降。

来源
Base.GC.enable函数
GC.enable(on::Bool)

使用布尔参数控制是否启用垃圾回收(true 表示启用,false 表示禁用)。返回之前的 GC 状态。

警告

禁用垃圾回收应谨慎使用,因为它会导致内存使用无限增长。

来源
Base.GC.@preserve
GC.@preserve x1 x2 ... xn expr

在表达式 expr 的评估期间,将对象 x1, x2, ... 标记为正在使用。这仅在不安全的代码中需要,在该代码中,expr隐式地使用x 之一拥有的内存或其他资源。

隐式使用 x 包含对 x 逻辑拥有的资源的任何间接使用,编译器无法看到这些资源。以下是一些示例

  • 通过 Ptr 直接访问对象的内存
  • 将指向 x 的指针传递给 ccall
  • 使用 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)
           # Preferred alternative
           Int(@ccall strlen(x::Cstring)::Csize_t)
       end
5
来源
Base.GC.safepoint函数
GC.safepoint()

在程序中插入一个点,垃圾回收可以在该点运行。这在多线程程序中很少见的用例中可能很有用,在这些用例中,一些线程正在分配内存(因此可能需要运行 GC),而其他线程只执行简单的操作(不分配、任务切换或 I/O)。在非分配线程中定期调用此函数允许垃圾回收运行。

Julia 1.4

此函数从 Julia 1.4 开始可用。

来源
Base.Meta.lower函数
lower(m, x)

获取表达式 x 并返回在模块 m 中执行的等效表达式,该表达式以降低的形式存在。另请参阅 code_lowered

来源
Base.Meta.@lower
@lower [m] x

返回模块 m 中表达式 x 的降低形式。默认情况下,m 是调用宏的模块。另请参阅 lower

来源
Base.Meta.parse方法
parse(str, start; greedy=true, raise=true, depwarn=true, filename="none")

解析表达式字符串并返回一个表达式(稍后可以传递给 eval 以执行)。startstr 中第一个字符的代码单元索引,从该索引开始解析(与所有字符串索引一样,这些不是字符索引)。如果 greedytrue(默认),parse 将尝试尽可能多地消耗输入;否则,它将在解析有效表达式后立即停止。不完整但语法上有效的表达式将返回 Expr(:incomplete, "(error message)")。如果 raisetrue(默认),则除了不完整表达式之外的语法错误将引发错误。如果 raisefalse,则 parse 将返回一个表达式,该表达式将在评估时引发错误。如果 depwarnfalse,则将抑制弃用警告。filename 参数用于在引发错误时显示诊断信息。

julia> Meta.parse("(α, β) = 3, 5", 1) # start of string
(:((α, β) = (3, 5)), 16)

julia> Meta.parse("(α, β) = 3, 5", 1, greedy=false)
(:((α, β)), 9)

julia> Meta.parse("(α, β) = 3, 5", 16) # end of string
(nothing, 16)

julia> Meta.parse("(α, β) = 3, 5", 11) # index of 3
(:((3, 5)), 16)

julia> Meta.parse("(α, β) = 3, 5", 11, greedy=false)
(3, 13)
来源
Base.Meta.parse方法
parse(str; raise=true, depwarn=true, filename="none")

贪婪地解析表达式字符串,返回单个表达式。如果第一个表达式之后还有其他字符,则会抛出错误。如果 raisetrue(默认),则语法错误将引发错误;否则,parse 将返回一个表达式,该表达式将在评估时引发错误。如果 depwarnfalse,则将抑制弃用警告。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")))
来源
Base.macroexpand函数
macroexpand(m::Module, x; recursive=true)

获取表达式 x 并返回在模块 m 中执行的等效表达式,其中所有宏都被删除(展开)。recursive 关键字控制是否还展开更深层的嵌套宏。这将在下面的示例中演示

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)
来源
Base.@macroexpand
@macroexpand

返回等效的表达式,其中所有宏都被删除(展开)。

@macroexpandmacroexpand 之间存在差异。

  • 虽然 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,表达式将在作为第一个参数给出的模块中扩展。

来源
Base.code_lowered函数
code_lowered(f, types; generated=true, debuginfo=:default)

返回与给定的泛型函数和类型签名匹配的方法的降低形式(IR)的数组。

如果 generatedfalse,则返回的 CodeInfo 实例将对应于回退实现。如果不存在回退实现,则会抛出错误。如果 generatedtrue,则这些 CodeInfo 实例将对应于通过展开生成器产生的方法体。

关键字 debuginfo 控制输出中存在的代码元数据的数量。

请注意,如果 types 不是叶类型,而 generatedtrue,并且任何对应的方法都是 @generated 方法,则会抛出错误。

来源
Base.code_typed函数
code_typed(f, types; kw...)

返回与给定的泛型函数和类型签名匹配的方法的类型推断降低形式(IR)的数组。

关键字参数

  • optimize::Bool = true:可选,控制是否还应用额外的优化,例如内联。
  • debuginfo::Symbol = :default:可选,控制输出中存在的代码元数据的数量,可能的选项是 :source:none

内部关键字参数

本节应视为内部内容,仅供了解 Julia 编译器内部机制的人员使用。

  • world::UInt = Base.get_world_counter():可选,控制查找方法时要使用的世界年龄,如果未指定,则使用当前世界年龄。
  • interp::Core.Compiler.AbstractInterpreter = Core.Compiler.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
来源
Base.precompile函数
precompile(f, argtypes::Tuple{Vararg{Any}})

为给定的参数元组(类型)argtypes 编译给定的函数 f,但不执行它。

来源
precompile(f, argtypes::Tuple{Vararg{Any}}, m::Method)

为给定的参数类型预编译特定方法。这可用于预编译与通常由调度选择的不同的方法,从而模拟 invoke

来源
Base.jit_total_bytes函数
Base.jit_total_bytes()

返回即时编译器为例如本机代码和数据分配的总字节数。

来源

Meta

Base.Meta.quot函数
Meta.quot(ex)::Expr

引用表达式 ex 以生成头部为 quote 的表达式。例如,这可用于表示 AST 中的 Expr 类型对象。另请参阅有关 QuoteNode 的手册部分。

示例

julia> eval(Meta.quot(:x))
:x

julia> dump(Meta.quot(:x))
Expr
  head: Symbol quote
  args: Array{Any}((1,))
    1: Symbol x

julia> eval(Meta.quot(:(1+2)))
:(1 + 2)
来源
Base.isexpr函数
Meta.isexpr(ex, head[, n])::Bool

如果 ex 是具有给定类型 headExpr,并且可选地参数列表的长度为 n,则返回 truehead 可以是 SymbolSymbol 集合。例如,要检查宏是否传递了一个函数调用表达式,可以使用 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]) # multiple possible heads
true

julia> Meta.isexpr(ex, :call, 1)
false

julia> Meta.isexpr(ex, :call, 2)
true
来源
Base.isidentifier函数
 isidentifier(s) -> Bool

返回符号或字符串 s 是否包含在 Julia 代码中解析为有效普通标识符(不是二元/一元运算符)的字符;另请参阅 Base.isoperator.

在内部,Julia 允许 Symbol 中的任何字符序列(除了 \0),并且宏会自动使用包含 # 的变量名,以避免与周围代码的命名冲突。为了让解析器识别变量,它使用了一组有限的字符(Unicode 大大扩展)。isidentifier() 使得可以直接查询解析器该符号是否包含有效字符。

示例

julia> Meta.isidentifier(:x), Meta.isidentifier("1x")
(true, false)
来源
Base.isoperator函数
isoperator(s::Symbol)

如果符号可以用作运算符,则返回 true,否则返回 false

示例

julia> Meta.isoperator(:+), Meta.isoperator(:f)
(true, false)
来源
Base.isunaryoperator函数
isunaryoperator(s::Symbol)

如果符号可以用作一元(前缀)运算符,则返回 true,否则返回 false

示例

julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f)
(true, true, false)
来源
Base.isbinaryoperator函数
isbinaryoperator(s::Symbol)

如果符号可以用作二元(中缀)运算符,则返回 true,否则返回 false

示例

julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f)
(true, false, false)
来源
Base.Meta.show_sexpr函数
Meta.show_sexpr([io::IO,], ex)

以 Lisp 风格的 S 表达式形式显示表达式 ex

示例

julia> Meta.show_sexpr(:(f(x, g(y,z))))
(:call, :f, :x, (:call, :g, :y, :z))
来源