# 与 MATLAB 的显著差异
虽然 MATLAB 用户可能会发现 Julia 的语法很熟悉,但 Julia 不是 MATLAB 的克隆。 它们之间存在重大的语法和功能差异。 以下是一些可能会使习惯于 MATLAB 的 Julia 用户感到困扰的显著差异:
- Julia 数组使用方括号
A[i,j]进行索引; - Julia 数组在分配给另一个变量时不会被复制。 在
A = B之后,改变B的元素也会改变A的元素; - Julia 的值在向函数传递时不发生复制。如果某个函数修改了数组,这一修改对调用者是可见的;
- Julia 不会在赋值语句中自动增长数组。 而在 MATLAB 中
a(4) = 3.2可以创建数组a = [0 0 0 3.2],而a(5) = 7可以将它增长为a = [0 0 0 3.2 7]。如果a的长度小于 5 或者这个语句是第一次使用标识符a,则相应的 Julia 语句a[5] = 7会抛出错误。Julia 使用push!(opens new window) 和append!(opens new window) 来增长Vector,它们比 MATLAB 的a(end+1) = val更高效; - 虚数单位
sqrt(-1)在 Julia 中表示为im(opens new window),而不是在 MATLAB 中的i或j; - 在 Julia 中,没有小数点的数字字面量(例如
42)会创建整数而不是浮点数。也支持任意大整数字面量。因此,某些操作(如2^-1)将抛出 domain error,因为结果不是整数(有关的详细信息,请参见 Julia 常见问题中的有关 domain errors 的条目 (opens new window))。 在 Julia 中,没有小数点的数字字面量(例如42)会创建整数而不是浮点数。因此,某些操作会因为需要浮点数而抛出 domain error;例如julia > a = -1; 2^a,因为结果不是整数了。请参见常见问题中有关 domain errors 的条目 (opens new window)); - 在 Julia 中,能返回多个值并将其赋值为元组,例如
(a, b) = (1, 2)或a, b = 1, 2。 在 Julia 中不存在 MATLAB 的nargout,它通常在 MATLAB 中用于根据返回值的数量执行可选工作。取而代之的是,用户可以使用可选参数和关键字参数来实现类似的功能; - Julia 拥有真正的一维数组。列向量的大小为
N,而不是Nx1。例如,rand(N)(opens new window) 创建一个一维数组; - 在 Julia 中,
[x,y,z]将始终构造一个包含x、y和z的 3 元数组;- 要在第一个维度(「垂直列」)中连接元素,请使用
vcat(x,y,z)(opens new window) 或用分号分隔([x; y; z]); - 要在第二个维度(「水平行」)中连接元素,请使用
hcat(x,y,z)(opens new window) 或用空格分隔([x y z]); - 要构造分块矩阵(在前两个维度中连接元素),请使用
hvcat(opens new window) 或组合空格和分号([a b; c d])。
- 要在第一个维度(「垂直列」)中连接元素,请使用
- 在 Julia 中,
a:b和a:b:c构造AbstractRange对象。使用collect(a:b)(opens new window) 构造一个类似 MATLAB 中完整的向量。通常,不需要调用collect。在大多数情况下,AbstractRange对象将像普通数组一样运行,但效率更高,因为它是懒惰求值。这种创建专用对象而不是完整数组的模式经常被使用,并且也可以在诸如range(opens new window) 之类的函数中看到,或者在诸如enumerate和zip之类的迭代器中看到。特殊对象大多可以像正常数组一样使用; - Julia 中的函数返回其最后一个表达式或
return关键字的值而无需在函数定义中列出要返回的变量的名称(有关详细信息,请参见 return 关键字 (opens new window)); - Julia 脚本可以包含任意数量的函数,并且在加载文件时,所有定义都将在外部可见。可以从当前工作目录之外的文件加载函数定义;
- 在 Julia 中,例如
sum(opens new window)、prod(opens new window) 和max(opens new window) 的归约操作会作用到数组的每一个元素上,当调用时只有一个函数,例如sum(A),即使A并不只有一个维度; - 在 Julia 中,调用无参数的函数时必须使用小括号,例如
rand()(opens new window); - Julia 不鼓励使用分号来结束语句。语句的结果不会自动打印(除了在 REPL 中),并且代码的一行不必使用分号结尾。
println(opens new window) 或者@printf(opens new window) 能用来打印特定输出; - 在 Julia 中,如果
A和B是数组,像A == B这样的逻辑比较运算符不会返回布尔值数组。相反地,请使用A .== B。对于其他的像是<(opens new window)、>(opens new window) 的布尔运算符同理; - 在 Julia 中,运算符
&(opens new window)、|(opens new window) 和⊻(opens new window)(xor(opens new window))进行按位操作,分别与MATLAB中的and、or和xor等价,并且优先级与 Python 的按位运算符相似(不像 C)。他们可以对标量运算或者数组中逐元素运算,可以用来合并逻辑数组,但是注意运算顺序的区别:括号可能是必要的(例如,选择A中等于 1 或 2 的元素可使用(A .== 1) .| (A .== 2)); - 在 Julia 中,集合的元素可以使用 splat 运算符
...来作为参数传递给函数,如xs=[1,2]; f(xs...); - Julia 的
svd(opens new window) 将奇异值作为向量而非密集对角矩阵返回; - 在 Julia 中,
...不用于延续代码行。不同的是,Julia 中不完整的表达式会自动延续到下一行; - 在 Julia 和 MATLAB 中,变量
ans被设置为交互式会话中提交的最后一个表达式的值。在 Julia 中与 MATLAB 不同的是,当 Julia 代码以非交互式模式运行时并不会设置ans; - Julia 的
struct不支持在运行时动态地添加字段,这与 MATLAB 的class不同。 如需支持,请使用Dict(opens new window)。Julia 中的字典不是有序的; - 在 Julia 中,每个模块有自身的全局作用域/命名空间,而在 MATLAB 中只有一个全局作用域;
- 在 MATLAB 中,删除不需要的值的惯用方法是使用逻辑索引,如表达式
x(x>3)或语句x(x>3) = []来 in-place 修改x。相比之下,Julia 提供了更高阶的函数filter(opens new window) 和filter!(opens new window),允许用户编写filter(z->z>3, x)和filter!(z->z>3, x)来代替相应直译x[x.>3]和x = x[x.>3]。使用filter!(opens new window) 可以减少临时数组的使用; - 类似于提取(或「解引用」)元胞数组的所有元素的操作,例如 MATLAB 中的
vertcat(A{:}),在 Julia 中是使用 splat 运算符编写的,例如vcat(A...); - 在 Julia 中,
adjoint函数执行共轭转置;在 MATLAB 中,adjoint提供了经典伴随,它是余子式的转置; - 在 Julia 中,a^b^c 被认为是 a^(b^c) 而在 MATLAB 中它是 (a^b)^c;
- Julia 语言在设计上注重数值精度和准确性。与 MATLAB 在某些显示细节上有所不同,Julia 会严格按照数值的实际存储情况进行显示,包括符号位。对于 -0.0 这个特殊的浮点数,Julia 能够准确地输出 -0.0,而 MATLAB 会显示成 0,如果想要在 MATLAB 精确地显示 -0.0,可以通过设置格式化输出来实现,例如
num = -0.0;str = sprintf('%f',num);disp(str)。