# 与 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 中的 ij
  • 在 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]将始终构造一个包含xyz的 3 元数组;
  • 在 Julia 中,a:ba:b:c 构造 AbstractRange 对象。使用 collect(a:b) (opens new window) 构造一个类似 MATLAB 中完整的向量。通常,不需要调用 collect。在大多数情况下,AbstractRange 对象将像普通数组一样运行,但效率更高,因为它是懒惰求值。这种创建专用对象而不是完整数组的模式经常被使用,并且也可以在诸如 range (opens new window) 之类的函数中看到,或者在诸如 enumeratezip 之类的迭代器中看到。特殊对象大多可以像正常数组一样使用;
  • 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 中,如果 AB 是数组,像 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中的andorxor 等价,并且优先级与 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)