与其他语言的显著差异¶
尽管 Julia 的语法对于 MATLAB 用户来说可能并不陌生,但它并不是 MATLAB 的克隆。两者在语法和功能上存在重要差异。以下是 Julia 中的一些显著差异,它们可能会让习惯使用 MATLAB 的用户感到困惑。
与 MATLAB 的区别¶
- Julia 中的数组索引用方括号指定:A[i,j]。
Pkg.add(["LinearAlgebra"])
A = [1 2 3; 4 5 6; 7 8 9]
i = 2
j = 3
element = A[i, j]
println(element)
2.当 Julia 中的数组被赋值给另一个变量时,它不会被复制。在赋值 A = B 后,改变 B 中的元素会导致 A 中的元素发生变化。
B = [1, 2, 3]
A = B
B[1] = 10
println(A)
3.在 Julia 中,传递给函数的值不会被复制。如果函数更改了数组,调用者将看到这些更改。
function modify_array(arr)
arr[1] = 100
end
A = [1, 2, 3]
modify_array(A)
println(A)
4.在 Julia 中,使用赋值运算符时数组不会自动扩大。在 MATLAB 中,您可以使用表达式 a(4) = 3.2 创建数组 a = [0 0 0 0 3.2],并使用表达式 a(5) = 7 将其扩展为 a = [0 0 0 0 3.2 7],而在 Julia 中,如果 a 的长度小于 5 或在此操作符中首次使用名称 a,相应操作符 a[5] = 7 就会出错。与 MATLAB 中的 a(end+1) = val 相比,Julia 的 push!和 append!函数可以更高效地递增 Vector 类型的对象。
A = [1, 2, 3]
push!(A, 4)
println(A)
B = [5, 6, 7]
append!(B, [8, 9])
println(B)
5.在 Julia 中,虚数单位 sqrt(-1) 用常数 im 表示,而不是 MATLAB 中的 i 或 j。
z = 2 + 3im
println(z)
println("Действительная часть: ", real(z))
println("Мнимая часть: ", imag(z))
6.在 Julia 中,没有小数分隔符的数字字面形式(例如 42)创建的是整数而不是浮点数。因此,如果某些操作期望使用浮点数,则可能会产生区域外错误。例如,julia> a = -1; 2^a 将产生这样的错误,因为结果不是整数(详情请参见常见问题中的区域外错误)。
a = 42 # целое число
b = 42.0 # число с плавающей запятой
c = float(42) # явное преобразование к типу Float64
println(a)
println(b)
println(c)
7.在 Julia 中,如果要返回或赋值多个值,则使用元组,例如 (a, b) = (1, 2) 或 a, b = 1, 2。Julia 没有 nargout 函数,而在 MATLAB 中,nargout 通常用于根据返回值的数量执行额外的操作。可选参数和命名参数可以用于类似的目的。
function get_values()
return 1, 2
end
x, y = get_values()
println(x)
println(y)
8.Julia 有真正的一维数组。列向量的大小是 N,而不是 Nx1。例如,rand(N) 表达式会创建一个一维数组。
v = [1, 2, 3] # одномерный массив
9.在 Julia 中,构造 [x,y,z] 总是创建一个包含三个元素的数组:x、y 和 z。- 要沿第一个维度("垂直")进行连接,请调用 vcat(x,y,z) 函数或使用分号([x; y; z])作为分隔符。- 要沿第二维("水平 "维)进行连接,请调用 hcat(x,y,z) 函数或使用空格([x y z])作为分隔符。- 要创建块矩阵(沿前两个维度进行连接),请调用 hvcat 函数或将空格和分号组合起来作为分隔符([a b; c d])。
A = [1, 2, 3]
B = [4, 5, 6]
C = [7, 8, 9]
D = vcat(A, B, C) # вертикальная конкатенация
println(D)
E = hcat(A, B, C) # горизонтальная конкатенация
println(E)
F = [A; B; C] # разделитель ";"
println(F)
G = [A B C] # разделитель пробел
println(G)
10.在 Julia 中,构造 a:b 和 a:b :c 可以创建 AbstractRange 对象。要创建一个完整的向量,就像在 MATLAB 中一样,使用 collect(a:b) 方法。不过,通常没有必要调用 collect。在大多数情况下,AbstractRange 对象的行为与普通数组类似,但由于可以 "懒惰 "地计算值,因此效率更高。这种创建特殊对象而非完整数组的模式经常被使用,包括 range 等函数以及 enumerate 和 zip 等迭代器。特殊对象通常可以像普通数组一样使用。
range = 1:5
vector = collect(range)
println(vector)
11.Julia 中的函数返回最后一个表达式或表达式的计算结果,并带有返回关键字。不必在函数定义中列出返回变量的名称(详见返回关键字部分)。
function sum(x, y)
x + y
end
result = sum(2, 3)
println(result)
12.在 Julia 中,调用不带参数的函数时,必须使用括号,例如 rand()。
function example()
println("Функция без аргументов")
end
example()
13.在 Julia 中,不建议在表达式的末尾加上分号。表达式的结果不会自动显示(交互式命令行除外),因此没有必要在代码行末尾加上分号。您可以使用 println 函数或 @printf 宏在屏幕上显示某些数据。
a = 2
b = 3
c = a + b
println(c)
14.在 Julia 中,如果 A 和 B 是数组,逻辑比较操作(如 A == B)不会返回逻辑值数组。相反,可以使用 A .== B 或类似的表达式来表示其他逻辑运算符,如 < 和 >。
A = [1, 2, 3]
B = [2, 2, 3]
result = A .== B
println(result)
15.在 Julia 中,运算符 &、| 和 ⊻ (xor) 是位运算符,就像 MATLAB 中的 and、or、and、or 和 xor 一样。它们的优先级与 Python 中位运算符的优先级相同(但与 C 语言不同)。它们可以应用于标量值,也可以逐元素应用于数组,还可以用于组合逻辑数组。但是,请注意操作顺序的不同:可能需要使用括号(例如,要选择 A 中等于 1 或 2 的元素,请使用表达式 (A .== 1) .| (A .== 2))。
a = 5
b = 3
result = a & b
println(result)
A = [true, false, true]
B = [false, true, true]
result = A .& B
println(result)
16.在 Julia 中,可以使用扩展运算符(splat 运算符)...将集合的元素作为参数传递给函数,例如 xs=[1,2]; f(xs...)。
function sum_elements(x, y, z)
return x + y + z
end
values = [1, 2, 3]
result = sum_elements(values...)
println(result)
17.Julia 中的 svd 函数以向量形式返回奇异值,而不是稠密的对角矩阵。
using LinearAlgebra
A = [1 2; 3 4]
U, S, V = svd(A)
println(S)
18.在 Julia 中,...不是用来续写代码的。相反,不完整的表达式会自动在下一行继续。
a = 2 +
3
println(a)
19.Julia 中的结构体(struct)不支持在运行时动态添加字段,这一点与 MATLAB 中的类(class)不同。请使用 Dict 代替。Julia 中的字典不是有序的。
struct MyStruct1
field1::Int
end
s = MyStruct1(10)
println(s.field1)
# Используем словарь для добавления поля field2
s_dict = Dict(:field1 => s.field1, :field2 => 20)
println(s_dict[:field2])
20.在 Julia 中,每个模块都有自己的全局区域或命名空间,而在 MATLAB 中只有一个全局区域。
module MyModule
global_var = 10
function my_function()
println(global_var)
end
end
MyModule.my_function()
21.在 MATLAB 中,移除不必要值的惯用方法是使用逻辑索引,如表达式 x(x>3) 或运算符 x(x>3) = [] 来改变 x 的位置。为此,Julia 提供了高阶函数 filter 和 filter! ,允许使用表达式 filter(z->z>3, x) 和 filter!(z->z>3, x) 替代 x[x.>3] 和 x = x[x.>3]。使用 filter! 函数可以减少使用临时数组的频率。
A = [1, 2, 3, 4, 5]
filtered_A = filter(x -> x > 3, A)
println(filtered_A)
filter!(x -> x > 3, A)
println(A)
22.提取(或 "取消引用")单元数组的所有元素,如 MATLAB 中的 vertcat(A{:}),在 Julia 中使用扩展运算符(splat 运算符),如 vcat(A...)。
A = [1, 2]
B = [3, 4]
C = [5, 6]
array_of_arrays = [A, B, C]
concatenated_array = vcat(array_of_arrays...)
println(concatenated_array)
23.在 Julia 中,adjoint 函数执行共轭转置;而在 MATLAB 中,adjoint 提供了adjoint 矩阵(经典adjoint),即执行代数补码矩阵的转置。
A = [1+2im 3+4im]
adj_A = adjoint(A)
println(adj_A)
24.在 Julia 中,表达式 (a ^ b ^ c) 的求值为 a^ (b^c),而在 MATLAB 中,表达式的求值为 (a ^ b) ^ c。
a = 3
b = 2
c = 3
result = a^(b^c)
println(result)
与 Python 的区别¶
1.在 Julia 中,代码块 for、if、while 等以结束关键字结束,而不是像 Python 那样缩进。没有 pass 关键字。
for i in 1:5
println(i)
end
2.在 Julia 中,字符串用双引号表示,多行文本使用三对双引号。此外,单引号用于表示字符。
str1 = "Hello, World!"
str2 = """Это много-
строчный текст."""
char1 = 'c'
3.Julia 使用 * 操作符来连接字符串,而不是 Python 中的 +。^ 操作符用于重复字符串,而不是 *。
str1 = "Hello, "
str2 = "World!"
concatenated_str = str1 * str2
repeated_str = str2 ^ 3
println(concatenated_str)
println(repeated_str)
4.在 Julia 中,列表对应于 Vector{Any} 类型或更通用的 Vector{T} 类型,其中 T 是某种元素类型。更高效的数组,如 NumPy 数组,可以用 Array{T} 数组表示,其中 T 是特定的元素类型。
list1 = Any[1, "two", 3.0]
list2 = Vector{Int}(undef, 5)
array1 = Array{Int}(undef, 3, 3)
5.Julia 中数组的索引从 1 开始,这与 Python 的索引从 0 开始不同。
array = [1, 2, 3, 4, 5]
println(array[1]) # Выведет 1
6.Julia 中的 a[2:3] 相当于 Python 中的 a[1:3]。
array = [1, 2, 3, 4, 5]
println(array[2:3]) # Выведет [2, 3]
7.在 Julia 中,允许使用任意索引的 AbstractArray。在 Python 中具有特殊含义的负指数在 Julia 中被写成 a[end] 和 a[end-1]。
array = [1, 2, 3, 4, 5]
println(array[end]) # Выведет 5
println(array[end - 1]) # Выведет 4
8.在 Julia 中,end 关键字用于索引最后一个元素。Python 中的 x[1:] 相当于 Julia 中的 x[2:end]。
array = [1, 2, 3, 4, 5]
println(array[2:end]) # Выведет [2, 3, 4, 5]
9.在 Julia 中,范围索引的格式是 x[start:step:stop],而在 Python 中是 x[start:(stop+1):step]。因此,Python 中的 x[0:10:2] 相当于 Julia 中的 x[1:2:10]。
array = [1, 2, 3, 4, 5]
println(array[1:2:end]) # Выведет [1, 3, 5]
10.Julia 没有字符串延续语法。如果一个字符串包含一个完整的表达式,它就被认为是完整的。否则,字符串将被继续。您可以使用括号来继续表达式。
a = (
1 + 2 +
3
)
println(a) # Выведет 6
11.在 Julia 中,数组是按列展开的,而 NumPy 数组是按行展开的。在 Julia 中循环数组时,循环顺序必须与 NumPy 相反。
A = [1 2; 3 4; 5 6]
for j in 1:size(A, 2), i in 1:size(A, 1)
println(A[i, j])
end
12.在 Julia 中,函数参数的默认值会在每次方法调用时进行评估,这与 Python 不同,后者只在定义函数时进行评估。
function f(x = rand())
return x
end;
println(f()) # Выполните ячейку несколько раз
13.在 Julia 中,命名参数必须与名称一起传递,这与 Python 不同。
function foo(a; b = 1, c = 2)
return a + b + c
end
println(foo(10, b = 3, c = 4)) # Выведет 17, нельзя вызывать как println(foo(10, 3, 4)), в случае с Python
14.在 Julia 中,Int 类型对应于机器整数类型(Int32 或 Int64),而在 Python 中,int 可以是任意长度。
x = Int64(2) ^ Int64(64)
println(x) # Выведет 0
15.在 Julia 中,虚数单位用常量 im 表示,而在 Python 中则使用 j。
println(2im) # Выведет 0 + 2im
16.在 Julia 中,度运算符用 ^ 表示,而不是 Python 中的 **。
println(2 ^ 3) # Выведет 8
17.Julia 中的空值用 Nothing 类型的常量 nothing 表示,而 Python 使用 NoneType 类型的 None 对象。
x = nothing
println(x) # Выведет nothing
18.在 Julia 中,* 操作符执行矩阵运算,而在 Python 中,它执行逐元素乘法。在 Julia 中,.* 操作符用于逐元素乘法运算。
A = [1 2;
3 4]
B = [5 6;
7 8]
println(A * B) # Выведет матрицу, [19 22; 43 50]
println(A .* B) # Выведет матрицу, [5 12; 21 32]
19.在 Julia 中,'运算符返回共轭向量,而在 Python 中,.T transpose 运算符返回原始向量。
x = [1 2 3]
println(x') # Выведет [1; 2; 3]
20.在 Julia 中,一个函数可以有多个具体实现(方法),这些实现(方法)是根据参数的类型来选择的。在 Python 中,一个函数只有一个实现,不支持多态性。
function square(x::Number)
return x * x
end
function square(x::String)
return string(x, x)
end
println(square(2)) # Выведет 4
println(square("hello")) # Выведет "hellohello"
21.Julia 中没有类,而是使用只包含数据而不包含方法的结构。
struct MyStruct
x::Int
y::Float64
end
function f(obj::MyStruct, z)
return obj.x + obj.y + z
end
my_obj = MyStruct(1, 2.5)
println(f(my_obj, 3.5)) # Выведет 7.0
22.在 Python 中调用一个类实例的方法就相当于在 Julia 中调用一个函数。
struct MyType
x::Int
end
function f(obj::MyType, y)
return obj.x + y
end
my_obj = MyType(10)
println(f(my_obj, 5)) # Выведет 15
23.Julia 中的结构只能有一个抽象超类,而 Python 中的类可以从多个超类继承。
abstract type Animal end
struct Dog <: Animal
name::String
end
struct Cat <: Animal
name::String
end
dog = Dog("Buddy")
cat = Cat("Whiskers");
24.在 Julia 中,三元运算符的写法是 x > 0 ?1 : -1,而 Python 则使用条件表达式 1 if x > 0 else-1。
x = 10
result = x > 0 ? 1 : -1
println(result) # Выведет 1
25.在 Julia 中,异常处理使用 try-catch-finally 结构,而 Python 则使用 try-except-finally。
try
# Код, который может вызвать исключение
catch ex
# Обработка исключения
finally
# Выполнение кода, который будет выполнен в любом случае
end
结论¶
本例展示了 Julia 与 Matlab 和 Python 在语法和功能上的主要区别。