Julia 简介/REPL
julia
程序默认情况下会启动交互式 REPL,即读取/评估/打印/循环。它允许您输入 Julia 代码表达式并立即看到评估结果打印在屏幕上。它
- Reads 您输入的内容;
- Evaluates 它;
- Prints 出返回值;然后
- Loops 回来并重复所有操作。
REPL 是开始尝试学习该语言的好地方。但是,它不是执行任何规模的严肃编程工作的最佳环境——为此,文本编辑器或交互式笔记本环境(例如 IJulia/Jupyter)是更好的选择。但使用 REPL 有一些优势:它很简单,而且无需任何安装或配置即可使用。它还内置了一个帮助系统。
您输入一些 Julia 代码,然后按回车/Enter 键。Julia 会评估您输入的内容并返回结果
julia> 42 <Return/Enter> 42 julia>
如果您使用的是 Jupyter(IPython)笔记本,您可能需要按 Control-Enter 或 Shift-Enter。
如果您不想看到打印出的表达式结果,请在表达式末尾使用分号
julia> 42; julia>
此外,如果您想访问在 REPL 中输入的最后一个表达式的值,它存储在变量 ans
中
julia> ans 42
如果您没有在第一行完成表达式,请继续输入直到完成。例如
julia> 2 + <Return/Enter>
现在 Julia 会耐心地等待您完成表达式
2 <Return/Enter>
然后您将看到答案
4 julia>
输入一个问号 ?
julia> ?
您将立即切换到帮助模式,并且提示符将变为黄色(在终端中)
help?>
现在您可以输入某件事的名称(函数名称应该不带括号)
help?> exit search: exit atexit textwidth process_exited method_exists indexin nextind IndexLinear TextDisplay istextmime exit(code=0) Stop the program with an exit code. The default exit code is zero, indicating that the program completed successfully. In an interactive session, exit() can be called with the keyboard shortcut ^D. julia>
注意帮助系统尝试找到所有与您输入的字母匹配的单词,并向您显示它找到的内容。
如果您想搜索文档,可以使用 apropos
和搜索字符串
julia> apropos("determinant") LinearAlgebra.det LinearAlgebra.logabsdet LinearAlgebra.logdet
您将看到一个列表,其中包含名称或描述中包含该字符串的函数。
julia> apropos("natural log") Base.log Base.log1p help?> log search: log log2 log1p log10 logging logspace Clong Clonglong Culong Culonglong task_local_storage log(b,x) Compute the base b logarithm of x. Throws DomainError for negative Real arguments.
等等。
如果您输入一个分号
julia> ;
您将立即切换到 shell 模式
shell>
(并且提示符将变为红色)。此模式下可用的命令是您的系统命令行 shell 使用的命令。在 shell 模式下,您可以输入任何 shell(即非 Julia)命令并查看结果
shell> ls file.txt executable.exe directory file2.txt
您如何退出 shell 模式取决于您的 Julia 版本
- 在 Julia 1.6 及更高版本中,shell 模式是“粘性”(持久性)。按 Backspace 作为第一个字符,或 CTRL+C,返回
julia>
提示符 - 在早期的 Julia 版本中,提示符会立即切换回
julia>
,因此您每次想发出 shell 命令时都必须输入一个分号。
如果您输入一个右括号作为第一个字符
julia> ]
您将立即切换到包模式
(v1.1) pkg>
这是您执行包管理任务的地方,例如添加包、测试包等等。
要在空白行上按 Backspace 或 CTRL+C 退出包模式。
以下是 REPL 提示符下可用的其他一些有用的交互式函数和宏
varinfo()
– 打印有关模块中导出的全局变量的信息
julia> varinfo() name size summary –––––––––––––––– ––––––––––– ––––––––––– Base Module Core Module InteractiveUtils 222.893 KiB Module Main Module ans 1.285 KiB Markdown.MD
@which
– 告诉您将为函数和特定参数调用哪个方法
julia> @which sin(3) sin(x::Real) in Base.Math at special/trig.jl:53
versioninfo()
– 获取 Julia 版本和平台信息
julia> versioninfo() Julia Version 1.1.0 Commit 80516ca202 (2019-01-21 21:24 UTC) Platform Info: OS: Linux (x86_64-pc-linux-gnu) CPU: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.1 (ORCJIT, ivybridge)
还有一个快速获取版本的方法
julia> VERSION v"1.1.0"
edit("pathname")
– 启动默认编辑器并打开文件pathname
以进行编辑
@edit rand()
– 启动默认编辑器并打开包含内置函数rand()
定义的文件
less("filename-in-current-directory")
– 在分页器中显示文件
clipboard("stuff")
– 将“东西”复制到系统剪贴板
clipboard()
– 将剪贴板内容粘贴到当前 REPL 行
dump(x)
– 在屏幕上显示有关 Julia 对象x
的信息
names(x)
– 获取模块x
导出的名称数组
fieldnames(typeof(x))
– 获取属于类型x
的符号的数据字段数组
TAB 键通常能够完成(或建议完成)您开始输入的名称。例如,如果我输入 w
然后按 TAB 键(当有多个选项时按两次),所有以 'w' 开头的当前可用函数都会列出
julia> w <TAB> wait walkdir which while widemul widen withenv write
这适用于 Julia 实体以及 shell 和包模式。例如,以下是如何从 Julia 内部导航到目录
shell> cd ~ /Users/me shell> cd Doc <TAB> shell> cd Documents/ shell> ls ...
请记住,您可以使用 ?
和输入其完整名称(或使用 TAB 完成)来获取有关函数的帮助。
TAB 完成也适用于 Unicode 符号:例如,输入 \alp
并按 TAB 键获取 \alpha
,然后再次按 TAB 键获取 α
。以及对于 Emoji:例如,输入 \:fe
并按 TAB 键获取 \:ferris_wheel:
,然后再次按 TAB 键获取 🎡。
您可以使用向上和向下箭头键查看以前命令的记录(并且您可以退出并重新启动而不会清除该历史记录)。因此,您不必重新输入一个长的多行表达式,因为您可以从历史记录中调出它。如果您输入了大量的表达式,您可以通过按 Ctrl-R 和 Ctrl-S 在前后搜索它们。
Julia 的 REPL 支持一些功能,使命令行输入更有效率,这些功能绑定到特定的按键组合。例如,Alt+b
向后一个词,而 Alt+f
向前一个词。完整的按键绑定列表以及自定义它们的说明可以在 REPL 文档 中找到。请注意,一些编辑器,例如 VS Code,可能会覆盖某些按键组合。
范围和性能
[edit | edit source]关于 REPL 的一个警告。REPL 在 Julia 的全局范围级别运行。通常,在编写更长的代码时,您会将代码放在函数内部,并将函数组织成模块和包。当您的代码被组织成函数时,Julia 的编译器会更有效地工作,并且您的代码运行速度会更快。在顶层还有一些事情您无法做到,例如为变量的值指定类型。
更改提示并自定义您的 Julia 会话
[edit | edit source]以下 Julia 文件在每次启动 Julia 时运行(除非您使用 startup-file=no
选项)。
~/.julia/config/startup.jl
这使您可以加载您知道以后会需要的任何包。例如,如果您想自动自定义您的 REPL 会话,您可以安装 Julia 包 OhMyREPL.jl (https://github.com/KristofferC/OhMyREPL.jl) ,它允许您自定义 REPL 的外观和行为,然后,在启动文件中
using OhMyREPL
如果您只想在每次启动 Julia 会话时设置提示,您只需添加以下说明
using REPL function myrepl(repl) repl.interface = REPL.setup_interface(repl) repl.interface.modes[1].prompt = "julia-$(VERSION.major).$(VERSION.minor)> " return end atreplinit(myrepl)
这只是将当前 REPL 提示设置为显示您的会话正在使用的 Julia 版本号。
Julia 和数学
[edit | edit source]您可以使用 Julia 作为强大的计算器,使用 REPL。这也是一个好习惯。(这是交互式编程语言介绍中的传统,也是认识语言的好方法。)
julia> 1000000 / 7 142857.14285714287
输入数字
[edit | edit source]世界上一半的人使用逗号 (,) 将长数字分成三组,另一半使用句点 (.)。(剩下的人使用科学计数法……)在 Julia 中,您可以使用下划线 (_) 来分隔数字组
julia> 1_000_000 - 2_015 997985
虽然您不会在响应中看到一个。
要使用科学计数法,只需输入“e”(或“E”)并且不要添加任何空格
julia> planck_length = 1.61619997e-34
要输入虚数,请使用 im
julia> (1 + 0.5im) * 2 2.0 + 1.0im
运算符作为函数
[edit | edit source]julia> 2 + 2 4 julia> 2 + 3 + 4 9
添加数字的等效形式是
julia> +(2, 2) 4
您通常在值之间使用的运算符是普通的 Julia 函数,并且可以像其他函数一样使用。同样
julia> 2 + 3 + 4 9
可以写成
julia> +(2, 3, 4) 9
和
julia> 2 * 3 * 4 24
可以写成
julia> *(2,3,4) 24
提供了一些数学常数
julia> pi π = 3.1415926535897...
您可以在 MathConstants 模块中找到其他数学常数
julia> Base.MathConstants.golden φ = 1.6180339887498... julia> Base.MathConstants.e e = 2.7182818284590...
所有常见的运算符都可用
julia> 2 + 3 - 4 * 5 / 6 % 7 1.6666666666666665
请注意运算符的优先级。在这种情况下,它是
((2 + 3) - ((4 * 5) / 6) % 7)
如果您想检查运算符的优先级,请将表达式括在 :(
和 )
中
julia> :(2 + 3 - 4 * 5 / 6 % 7) :((2 + 3) - ((4 * 5) / 6) % 7)
(有关此内容的更多信息,请参阅 元编程)。
乘法通常写成 *
,但当将变量乘以数字文字时,可以省略。
julia> x = 2 2 julia> 2x + 1 5
julia> 10x + 4x - 3x/2 + 1 26.0
这使得方程更容易编写。
有时您需要括号来控制求值顺序
julia> (1 + sqrt(5)) / 2 1.618033988749895
需要注意的其他一些运算符包括
^
幂%
余数
要创建有理数,请使用两个斜杠 (//
)
julia> x = 666//999 2//3
从技术上讲,/
表示“右除”。还有左除“\
”。对于数字,x/y
= y\x
。但是,对于向量和矩阵,x = A\y
解 A*x = y
,而 x = y/A
解 x*A = y
。
标准算术运算符还有一些特殊的更新版本,您可以使用它们快速更新变量
+=
-=
*=
/=
\=
%=
^=
例如,在定义一个变量 x
后
julia> x = 5 5
您可以为它添加 2
julia> x += 2 7
然后将其乘以 100
julia> x *= 100 700
然后将其简化为模 11 值
julia> x %= 11 7
有一些按元素运算符可以作用于数组。这意味着您可以按元素乘以两个数组
julia> [2,4] .* [10, 20] 2-element Array{Int64,1}: 20 80
数组是 Julia 的基础,因此在本书中拥有自己的章节。
如果您使用 /
除两个整数,答案始终是浮点数。如果您使用过 Python 版本 2,您会记得 Python 返回一个整数结果。Python (3) 现在返回一个浮点数。
Julia 提供了一个整数除法运算符 ÷(键入 \div TAB
,或使用函数版本 div()
。当您想要整数结果而不是 /
返回的浮点数时,应该使用此运算符。
julia> 3 ÷ 2 1 julia> div(3, 2) 1
请注意,Julia 不会将答案转换为整数类型,即使结果实际上是一个整数。
julia> div(3, 2.0) 1.0
这是为了避免类型不稳定问题,这会减慢您的代码速度。
整数溢出
[edit | edit source]如果您认为您的计算将超出 64 位限制,请通过将 big
函数应用于操作数来选择大整数,并将它们存储为大数
julia> 2^64 # oops 0 julia> big(2)^64 # better 18446744073709551616 julia> 2^big(64) # equally better 18446744073709551616
要获得 Julia 程序的最快执行速度,您应该了解如何存储您的数据和变量,而不会引入“类型不稳定”。
进制
[edit | edit source]在使用 REPL 作为计算器时,这些方便的实用程序函数可能会有用。
bitstring()
函数显示数字的文字二进制表示形式,如存储的那样
julia> bitstring(20.0) "0100000000110100000000000000000000000000000000000000000000000000" julia> bitstring(20) "0000000000000000000000000000000000000000000000000000000000010100"
请注意,浮点数“版本”的存储方式与预期一样。
要从二进制字符串返回到十进制,您可以使用 parse()
,它接受目标类型和进制
julia> parse(Int, "0000011", base=2) 3 julia> parse(Int, "DecaffBad", base=16) 59805531053
要以 10 以外的进制工作,请使用 string
函数将整数转换为字符串
julia> string(65535, base=16) "ffff" julia> string(64, base=8) "100"
而 digits(number, base=b)
返回一个数组,该数组包含 number
在给定进制中的数字
julia> digits(255, base=16) 2-element Array{Int64,1}: 15 15
变量
[edit | edit source]在此表达式中
julia> x = 3
x
是一个变量,是数据对象的命名存储位置。在 Julia 中,变量的命名方式几乎可以随心所欲,但不要以数字或标点符号开头变量名。如果需要,您可以使用 Unicode 字符。
要分配值,请使用一个等号。
julia> a = 1 1 julia> b = 2 2 julia> c = 3 3
要测试相等性,您应该使用 ==
运算符或 isequal()
函数。
在 Julia 中,您也可以同时分配多个变量
julia> a, b = 5, 3 (5,3)
请注意,此表达式的返回值是一个括号包围的逗号分隔的元素有序列表:简称为元组。
julia> a 5 julia> b 3
数字和变量相乘
[edit | edit source]值得重复的是,您可以用数字开头变量名来相乘它们,而不必使用星号 (*
)。例如
julia> x = 42 42 julia> 2x 84 julia> .5x 21.0 julia> 2pi 6.283185307179586
特殊字符
[edit | edit source]Julia REPL 提供了对特殊字符的轻松访问,例如希腊字母字符、下标和特殊数学符号。如果您键入反斜杠,那么您可以键入一个字符串(通常是等效的 LATEX 字符串)来插入相应的字符。例如,如果您键入
julia> \sqrt<TAB>
Julia 用一个平方根符号替换了 \sqrt。
julia> √
其他一些例子
\pi | π |
\Gamma | Γ |
\mercury | ☿ |
\degree | ° |
\cdot | ⋅ |
\in | ∈ |
完整的列表在 Julia 源代码中。作为一般原则,在 Julia 中,建议您查看源代码,因此有一些有用的内置函数可以查看 Julia 源文件。例如,在 macOS 上,这些符号存储在
julia> less("/Applications/Julia-1.0.app/Contents/Resources/julia/share/julia/stdlib/v1.0/REPL/src/latex_symbols.jl")
less
会通过分页器运行文件(即 Unix 中的 less
命令)。如果您胆大,可以尝试使用 edit()
而不是 less()
。这将启动一个编辑器并打开文件。
您也可以在 REPL 中使用 Emoji 和其他 Unicode 字符。
对于 emoji,在反斜杠后输入 Emoji 字符名称,并在冒号之间,然后按 <TAB>
julia> \:id: <TAB>
这将变为
julia> 🆔
您可以在 https://docs.julia-lang.cn/en/latest/manual/unicode-input/#Unicode-Input-1
中找到列表。
输入不在此列表中的 Unicode 符号是可能的,但更依赖于操作系统:在 macOS 上,您在键入 Unicode 十六进制数字时“按住”Ctrl/Alt 键(在启用 Unicode 十六进制输入键盘的情况下);在 Windows 上,它是 Ctrl+Shift+u 后面跟着十六进制数字。
julia> ✎ = 3 3 julia> ✎ 3
数学函数
[edit | edit source]由于 Julia 特别适合科学和技术计算,因此您可以立即使用许多数学函数,而且您通常不必导入它们或使用前缀——它们已经可用。
三角函数期望以弧度为单位的值
julia> sin(pi / 2) 1.0
但也有基于度的版本:sind(90)
查找 90 度的正弦。使用 deg2rad()
和 rad2deg()
在度和弧度之间转换。
还有很多对数函数
julia> log(12) 2.4849066497880004
以及精确的 hypot()
函数
julia> hypot(3, 4) 5.0
norm()
函数(在通过“using LinearAlgebra”加载后)返回向量或矩阵的“p”范数。这是 divrem()
julia> divrem(13, 3) # returns the division and the remainder (4,1)
还有数十种其他函数。
有一个名为 ans
的系统范围内的变量,它会记住最近的结果,以便您可以在下一个表达式中使用它。
julia> 1 * 2 * 3 * 4 * 5 120 julia> ans/10 12.0
练习
[edit | edit source]猜猜,然后使用帮助系统找出 mod2pi()
和 isapprox()
是做什么的。
此处描述了与 Julia 一起提供的所有标准函数:[1]
随机数
[edit | edit source]rand()
– 获取一个介于 0 和 1 之间的随机 Float64
julia> rand() 0.11258244478647295
rand(2, 2)
– 一个维度为 2, 2 的 Float64 数组
rand(type, 2, 2)
– 一个维度为 2, 2 的此类型值的数组
rand(range, dims)
– 在一个范围内(包括两个端点)的数字数组,具有指定的维度
julia> rand(0:10, 6) 6-element Array{Int64,1}: 6 7 9 6 3 10
(有关范围对象的更多信息,请参见数组章节。)
如果告诉它,rand()
函数可以通过传递 Bool 关键字来生成一个真或假值
julia> rand(Bool) false
或一堆真值和假值
julia> rand(Bool, 20) 20-element Array{Bool,1}: false true false false false true true false false false false false false false true true false true true false
分布中的随机数
[edit | edit source]randn()
为您提供一个均值为 0,标准差为 1 的正态分布中的随机数。randn(n)
为您提供 n 个这样的数字
julia> randn() 0.8060073309441075 julia> randn(10) 10-element Array{Float64,1}: 1.3261528248041754 1.9203896217047232 -0.17640138484904164 1.0099294365771374 -0.9060606885634369 1.739192165935964 1.375790854463711 -0.6581841725500879 0.11190904953985797 2.798450557786332
如果您已经安装了 Plots 绘图包,您可以绘制它
julia> using Plots; gr()
julia> histogram(randn(10000), nbins=100)
播种随机数生成器
[edit | edit source]Random 包包含更多随机函数,例如 randperm()
、shuffle()
和 seed!
。
在使用随机数之前,您可以使用特定值播种随机数生成器。这确保了后续的随机数将遵循相同的序列,如果它们从同一个种子开始。您可以使用 seed!()
或 MersenneTwister()
函数播种生成器。
添加 Random 包后,您可以执行
julia> using Random julia> Random.seed!(10); julia> rand(0:10, 6) 6-element Array{Int64,1}: 6 5 9 1 1 0
julia> rand(0:10, 6) 6-element Array{Int64,1}: 10 3 6 8 0 1
重新启动 Julia 后,相同的种子保证相同的随机数。
简单的键盘输入
[edit | edit source]以下是如何编写和运行从键盘读取输入的函数的示例
julia> function areaofcircle() print("What's the radius?") r = parse(Float64, readline(stdin)) print("a circle with radius $r has an area of:") println(π * r^2) end areaofcircle (generic function with 1 method) julia> areaofcircle() What's the radius? 42 a circle with radius 42.0 has an area of: 5541.769440932395 julia>
这在 Julia REPL 会话中有效;当调用时,该函数会等待用户在键盘上键入字符串并按回车/Enter 键。