Julia 学习笔记——1. 基础
概述
Julia是一门新兴的科学计算语言,它的设计目标非常宏大:希望 Julia 可以同时拥有 Python/MATLAB 一样的易用性和 C/C++/Fortran 一样的运算效率。
Julia有很多与众不同的特点:
- 从计算效率的角度,虽然和Python在使用时很相似,但是Julia的计算效率却比Python高很多。Python的科学计算模块Numpy等必须依赖于C/C++编写的底层库,但是Julia自身就可以提供足够的科学计算能力(主要是通过预编译实现的)。
- 从语法设计的角度,Python并没有关注于科学计算编程中的便利性,Julia和MATLAB、Fortran、R语言的定位类似,充分为科学计算的效率和便利性考虑,提供了足够多的语法糖。这些语法糖其实有利有弊,一个典型的特征是索引从0还是从1开始,选择从1开始的语言具有明显的科学计算定位。
- 作为一种新兴语言,采用了很多较新颖的语法设计,比如抛弃了传统的面向对象编程,仅支持C风格的结构体等。
但是Julia还是有很多争议的,比如:
- Julia的发展时间太短了,主要的语法特性并不稳定;
- 各种基础库不如其它语言全面和健壮,甚至有的基础库还存在低级问题;
- 用户群体相比其他语言太小,相应的教程和第三方库也不够丰富。
综合考虑,还是简单学习一下吧。
与 MATLAB/Python 的语法对比
Julia 的语法非常像 Python(Numpy) 和 MATLAB 的缝合怪,主要呈现如下特征:
- Julia 舍弃了 MATLAB 在语法设计上的很多历史包袱;
- Julia 的设计目标并不是 Python 那样的通用语言,专门针对科学计算进行了很多语法设计,提供了很多语法糖,语句更加简洁;
- 虽然都属于动态语言,但是 Julia 为了实现高效运算,在语法设计上相比于 Python/MATLAB 更加“静态”化。
为了避免混淆,在学习 Julia 之前非常有必要了解一下它们的主要差异(下面对于 Python 的讨论默认包含 Numpy)。
Julia 有很多内容与 MATLAB 非常类似,与 Python 则有明显差异:
- 关于语法结构:Julia 使用
end
标记结束,而不是像Python一样完全依赖代码缩进,Julia对代码缩进并不敏感。 - 关于索引和切片:
- Julia 索引从 0 开始(Python 索引从 1 开始);
- Julia 使用
end
代表最后的元素(Python 使用-1
代表最后的元素) - Julia 的切片语法为
start:step:stop
,步长在中间,范围是严格闭区间(Python 切片语法是start:stop:step
,步长在最后,范围是左闭右开) - Julia
的切片语法比较严格,不允许缺省起点终点,例如
a[2:end]
不可以省略end
- Numpy 的高级索引非常奇怪(不是张量积),Julia 在类似情况采用了与 MATLAB 相似的处理。
- 关于数组底层:Julia 采用列优先排序,Numpy 主要采用行优先排序。
- 关于矩阵操作:
- Julia 使用
*
可以直接进行矩阵乘法,而 Python 需要使用@
。 - Julia 使用
'
表示转置,而 Python 则需使用.T
。
- Julia 使用
Julia 有很多内容与 Python 非常类似,与 MATLAB 则有明显差异:
- 关于语句结束:Julia 的语句不鼓励使用
;
结束,但是使用并不报错,(除了在 REPL 中)并不会像 MATLAB 那样自动打印语句的结果。 - 关于注释:Julia 使用
#
表示注释,MATLAB 则使用%
表示注释。 - 关于数据类型:
- Julia 对于整数和浮点数等的区分比较严格,在实际运算时可能自动转换,也可能需要显式转换。
- Julia 的整数类型通常是固定位数的,并不是 Python 那样的任意精度整数,这主要是为了运算效率考量。
- MATLAB 几乎不需要关注数据类型,绝大多数情况下使用默认的浮点数即可。
- 关于数组操作:
- Julia 使用
a[i,j]
访问数组元素,而 MATLAB 使用a(i,j)
。 - Julia 中的数组尺寸相对固定,不允许在赋值过程中自动增长数组。
- Julia 使用
- 关于拷贝机制:Julia 在赋值和传参过程中并不会发生拷贝,存在浅拷贝和视图等复杂机制,MATLAB 则采用值传递+懒拷贝机制。
- 关于空值:Julia 使用
nothing
专门表示空值,MATLAB 则通常使用[]
。 - 关于函数:
- Julia 支持函数参数默认值,但是 Python 的默认值求值只发生在定义时,Julia的默认值求值发生在每一次调用时。
- Julia 关于关键字参数,但是 Python 允许以位置参数传递,Julia 严格区分位置参数和关键字参数的使用。
- MATLAB 并不直接支持参数默认值和关键字参数,需要通过其它技巧实现。
Julia 还有一些内容介于 MATLAB 和 Python 之间:
- 关于列表或数组:Julia 提供的
Vector{Any}
数组比较高效,Python 的原生列表灵活但非常缓慢,Numpy 数组则比较类似。 - 关于字面量:
- Julia 将整数字面量例如
42
视作合适位数的整数类型,Python 统一视作任意精度整数,MATLAB 则统一视作浮点数。 - Julia 的复数单位为
im
,MATLAB的复数单位为i
和j
,Python的复数单位只有j
。 - Julia 只支持双引号的字符串,Python 单引号和双引号均可,MATLAB 的单引号是字符数组,双引号则是字符串,两者属于不同类型。
- Julia 将整数字面量例如
- 关于运算符:
- Julia 支持
+=
等运算符,但是与 Numpy 数组不同,默认情况下并不是就地运算,MATLAB 完全不支持这类运算符。 - Julia 有很多专门的逐点运算符,并且在语法上严格区分普通运算符和驻点运算符,比 MATLAB 和 Python 的处理都更加严格。
- Julia 使用
^
表示指数运算,与 MATLAB 相同,而 Python 使用**
。 - Julia 使用
!=
表示不等号,而 MATLAB 使用~=
。 - Julia 使用
%
表示取余,Python 使用%
表示模运算,两者在处理负数时存在差异。(MATLAB 的%
用于表示注释) - Julia 支持三元运算符
x > 0 ? 1 : -1
,MATLAB 不支持,Python 则有类似的条件表达式1 if x > 0 else -1
。
- Julia 支持
- 关于布尔值:Julia 在
if
语句等只能使用显式的布尔值,或者将其它语句显式转换为布尔值,甚至不支持 0 和 1 的隐式转换,而 MATLAB 和 Python 允许很多情况下的隐式转换。 - 关于续行:Julia 不需要续行语法,不完整的表达式会自动续行,MATLAB
使用
...
续行,Python 使用\
续行。 - 关于代码作用域:Julia 的大多数代码块都会引入新的局部作用域(与 C/C++ 类似),比 Python 的情况更多,而 MATLAB 除了默认的工作区之外,几乎只有函数可以开辟独立的工作区。
ans
:- 在 REPL 中,Julia 使用
ans
存储上一条命令的结果,MATLAB 也使用ans
,Python 则使用_
。 - 在非交互式模式中,Julia 和 Python 都不会专门存储上一条命令结果,而 MATLAB 总是会设置。
- 在 REPL 中,Julia 使用
- 关于面向对象:Julia 完全舍弃了面向对象,结构体只能用于存储数据,并且不能动态修改,MATLAB 和 Python 都支持面向对象机制。
- 关于函数调用:
- Julia 为所有函数提供了动态分派机制(类似于函数重载?其实更类似于C++的虚函数),MATLAB 有类似的动态重载机制,Python 不支持函数重载。
- Julia 即使无参数的函数调用也不允许省略括号,例如
rand()
(也只有MATLAB才有这种垃圾语法)
- 关于 for 循环和向量化:
- MATLAB 和 Python 的 for 循环非常慢,通常必须使用向量化语法;
- Julia 直接采用 for 循环已经足够高效,但是也支持向量化。
- 关于全局变量:全局变量的存在对于运算效率的影响都是负面的,尤其对于 Julia 的 for 循环影响很大。
- 关于函数返回值:
- Julia 可以使用
return
关键字返回结果,或者将最后一个表达式自动返回; - Python 使用
return
关键字返回结果,否则在缺省时只会返回None
; - MATLAB 必须在函数定义时声明返回值,
return
语句完全不携带返回值,只是提前结束。
- Julia 可以使用
除此之外,Julia 还有一些参考其它语言(例如 Lisp)的语法:
- 完全支持 Unicode 字符,包括中文和其它各种特殊符号;
- 支持名称为
@
开头的宏,并且宏的功能并不是类似于C语言中简单文本替换,而是支持更复杂的代码转换; - 按照约定,如果在函数名称的结尾有
!
(这是函数名称的一部分),表示这个函数会修改参数,例如push!
。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments