Introducing Julia/The REPL
REPL 环境
[编辑]默认情况下,键入 julia
将启动一个交互式 REPL,即读取/求值/打印/循环。它允许您在 Julia 代码中键入表达式,并立即在屏幕上看到计算结果。
- Reads what you type (读取你输入的内容)
- Evaluates it (求值)
- Prints out the return value, then (打印出返回值,然后)
- Loops back and does it all over again (返回并周而复始)
REPL 是一个开始尝试这种语言的好地方。但是对于正式代码编写,文本编辑器或交互式笔记本环境 (例如 IJulia/Jupyter) 才是更好的选择。
REPL 的优势在于:它很简单,不需要任何安装或配置就可以工作,还有一个内置的帮助系统。通过它你可以快速的验证一些想法。总而言之,它很适合用于学习 Julia.
使用 REPL
[编辑]键入一些 Julia 代码,然后键入 Return/Enter。Julia 将计算您键入的内容并返回结果:
julia> 42 <Return/Enter> 42 julia>
如果您使用的是 Jupyter (IPython) notebook,则可能必须键入 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.
诸如此类。
Shell 模式
[编辑]如果键入分号
julia> ;
立即切换到 shell 模式:
shell>
(提示变为红色)。在shell模式下,您可以键入任何shell(即非Julia)命令并查看结果:
shell> ls file.txt executable.exe directory file2.txt julia>
然后提示符切换回julia,因此每次想执行shell命令时,都必须键入分号。该模式下可用的命令是系统 shell 的命令。
包管理模式
[编辑]如果键入右方括号作为第一个字符:
julia> ]
立即切换到 package 模式:
v1.0 pkg>
这是您执行包管理任务的地方,例如添加包、测试包等等。
要离开 package 模式,请在空行上按 Backspace 或 CTRL+C。
内置函数和宏
[编辑]以下是在REPL提示中提供的一些有用的交互函数和宏:
- varinfo() – 打印有关 module 中导出的全局变量的信息。
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.0.0-rc1.0 Commit f92a55a06a (2018-08-07 16:29 UTC) Platform Info: OS: macOS (x86_64-apple-darwin14.5.0) CPU: Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.0 (ORCJIT, skylake) Environment: JULIA_EDITOR = mvim
还有一种快速查找版本的方法:
julia> VERSION v"1.0.0"
- edit("pathname") – 启动默认编辑器并打开文件
pathname
进行编辑
- @edit rand() – 启动默认编辑器并打开包含定义了内置函数
rand()
的文件
- less("filename-in-current-directory") – 在当前位置显示文件
- clipboard("stuff") – 复制 "stuff" 到系统剪贴板
- clipboard() – 将剪贴板的内容粘贴到当前 REPL 行中
- dump(x) – 在屏幕上显示有关Julia对象
x
的信息
- names(x) – 获取 module
x
所以导出的名称的数组。
- fieldnames(typeof(x)) – 获取属于类型为
x
的符号的数据字段的数组。
<TAB>
键: 自动补全
[编辑]TAB 键通常能够完成或建议完成您键入其名称的某项内容。例如,如果我键入w
,然后按Tab键(在有多个选项时按两次),则会列出以“w”开头的所有当前可用函数:
julia> w <TAB> wait walkdir which while widemul widen withenv write
这既适用于 Julia 实例,也适用于 shell 和 package 模式。例如,下面是如何从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来前后搜索它们。
变量作用域与性能
[编辑]一个关于 REPL 的警告。REPL 在 Julia 的 全局范围 内运行。
通常,当编写较长的代码时,您会将代码放在函数中,并将函数组织到模块和包中。当您的代码被组织成函数时,Julia的编译器工作得更有效,因此您的代码将运行得更快。
还有一些事情在 top level 是做不到的:比如为变量的值指定类型。
更改提示符并自定义 Julia 会话
[编辑]每次启动Julia时,都会运行以下 Julia 文件(除非使用startup-file=no
选项)。
~/.julia/config/startup.jl
这使您可以加载任何您所知的以后需要的包。例如,如果要自动定制 REPL 会话,可以安装能在启动文件中自定义REPL的外观和行为的包 OhMyREPL.jl (https://github.com/KristofferC/OhMyREPL.jl) ,然后在 startup 文件中:
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 与 数学
[编辑]你把 Julia REPL 当作一个强大的计算器。这也是很好的练习。(这是介绍交互式编程语言的传统,也是认识该语言的好方法。)
输入长数字
[编辑]世界上一半的人使用逗号(,)将长数字分成三组,另一半使用句点(.)。(我们其余的人使用科学记法)。
在Julia中,可以使用下划线(_)分隔:
julia> 1_000_000 - 2_015 997985
尽管你在返回的结果中看不到。
要使用科学符号,只需键入“e”,并记住不要使用空格:
julia> planck_length = 1.61619997e-34
我的电脑有多快?(每秒执行多少个十亿次的浮点运算)
julia> peakflops() / 1e9 48.778354495441356 julia> peakflops() / 1e9 54.20509453559899
(请注意第二次速度更快,这是因为 Julia 的编译起作用了。)
操作符即函数
[编辑]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 还提供了一些数学常量:
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
之后:
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
整型数溢出
[编辑]如果您认为您的计算将突破64位限制,请通过使用 big 函数将操作数存储为大数来选择“大整数”:
julia> 2^64 # oops 0 julia> big(2)^64 # better 18446744073709551616 julia> 2^big(64) # equally better 18446744073709551616
要为Julia程序获得最快的执行速度,您应该了解如何在不引入“类型不稳定”的情况下存储数据和变量。
进制转换
[编辑]当使用 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)
返回给定基数的数字位的数组 :
julia> digits(255, base=16) 2-element Array{Int64,1}: 15 15
变量
[编辑]在这个表达式中:
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
数字和变量相乘
[编辑]值得重复的是,您可以在变量名称前面加上一个数字来将其相乘,而不必使用星号(*
)。例如:
julia> x = 42 42 julia> 2x 84 julia> .5x 21.0 julia> 2pi 6.283185307179586
特殊符号
[编辑]JuliaREPL提供了对特殊字符的简单访问,例如希腊字母字符、下标和特殊的数学符号。如果键入反斜杠,则可以键入字符串(通常是等效的LaTeX字符串)以插入相应的字符。例如,如果键入以下内容:
julia> \sqrt <TAB>
Julia 会将 \sqrt 替换为平方根符号:
julia> √
其他一些例子:
\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
通过 pager 运行文件(即 Unix 中的 less命令)如果您很勇敢,请尝试使用 edit() 而不是 less(). 这将启动一个编辑器并打开文件。
还可以在REPL中使用Emoji和其他Unicode字符。
对于emoji,键入Emoji字符名称,在冒号之间,在反斜杠后面,然后按<TAB>:
julia> \:id: <TAB>
会更改为:
julia> 🆔
您可以在 https://docs.julialang.org/en/latest/manual/unicode-input/#Unicode-Input-1 找到列表.
输入不在此列表中的Unicode符号是可能的,但更依赖于操作系统:在MacOS上,在键入Unicode十六进制数字时按住 Ctrl/Alt键(启用Unicode十六进制键盘);在Windows上,输入Ctrl+Shift+u,后跟十六进制数字。)
julia> ✎ = 3 3 julia> ✎ 3
数学函数
[编辑]因为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() 函数返回向量的 "p" 范数或矩阵的算子范数。下面是 divrem():
julia> divrem(13, 3) # returns the division and the remainder (4,1)
There are dozens of others.
有一个称为ans
的系统范围的变量,它会记住最近的结果,因此您可以在下一个表达式中使用它。
julia> 1 * 2 * 3 * 4 * 5 120 julia> ans/10 12.0
小练习
[编辑]猜猜看,然后使用帮助系统了解 mod2pi() 和 isapprox() 做了什么。
这里描述了作为Julia标准提供的所有函数:[1]
随机数
[编辑]rand() – 获取一个介于0和1之间的随机 Float64 数值。
julia> rand() 0.11258244478647295
rand(2, 2) – 维数为 2, 2 类型为 Float64 的数组
rand(type, 2, 2) – 维数为 2, 2 类型为 type 的数组
rand(range, dims) – 具有指定的范围内(包括两端)的数字数组:
julia> rand(0:10, 6) 6-element Array{Int64,1}: 6 7 9 6 3 10
(有关范围对象的详细信息,请参见数组一章。)
The rand() function can generate a true or false value if you tell it to, by passing the Bool keyword:
如果传递 Bool 关键字给 rand() 函数,它可以生成 true 或 false 值:
julia> rand(Bool) false
或是一堆 true 和 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
服从分布的随机数
[编辑]randn() 给出正态分布中的一个随机数,平均值为0,标准差为1。randn(n) 给出 n 个这样的数字:
julia> randn() 0.8060073309441075 julia> randn(10), ([1.31598,1.55126,-1.14605,-0.562148,0.69725,0.468769,-1.58275,0.238471,2.72857,1.11561],)
( randn(10) 后面的逗号仅用于行的可视化)
如果已安装 Plots 包,则可以打印以下内容:
julia> using Plots; gr()
julia> histogram(randn(10000), nbins=100)
设置随机数种子
[编辑]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后,相同的种子保证相同的随机数。
简单的输入示例
[编辑]下面是一个简单的示例,说明如何编写和运行从键盘读取输入的函数:
julia> function areaofcircle() println("What's the radius?") r = parse(Float64, readline(stdin)) println("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>