与其他语言值得注意的区别
与MATLAB值得注意的区别
虽然MATLAB用户可能会发现Julia的语法很熟悉,但Julia不是MATLAB克隆。 有主要的语法和功能差异。 以下是一些值得注意的差异,可能会绊倒习惯于MATLAB的Julia用户:
*Julia数组用方括号索引, A[i,j].
*Julia数组在分配给另一个变量时不会被复制。 之后 A=B,改变元素 B 会修改 A ""好吧。 为了避免这种情况,使用 A=复制(B).
*传递给函数时不会复制Julia值。 如果函数修改数组,则更改将在调用方中可见。
*Julia不会在赋值语句中自动增长数组。 而在MATLAB中 a(4)=3.2 可以创建数组 a=[0 0 0 3.2] 和 a(5)=7 能长成 a=[0 0 0 3.2 7],对应的Julia语句 a[5]=7 如果长度为 a 小于5,或者如果此语句是标识符的首次使用 a. 朱莉娅有 推!和 追加!,其中生长 向量资料它比MATLAB的效率高得多 a(end+1)=val.
*虚数单位 sqrt(-1) 在Julia中表示为 我,不 i 或 j 如在MATLAB中。
*在Julia中,没有小数点的文字数字(如 42)创建整数而不是浮点数。 因此,如果某些操作期望浮点数,则可能引发域错误;例如, 朱莉娅>a=-1;2^a 抛出域错误,因为结果不是整数(请参阅 关于域错误的常见问题条目有关详细信息)。
*在Julia中,返回多个值并将其分配为元组,例如 (a,b)=(1,2) 或 a,b=1,2. MATLAB的 纳格特,在MATLAB中经常用于根据返回值的数量做可选工作,在Julia中不存在。 相反,用户可以使用可选参数和关键字参数来实现类似的功能。
*Julia有真正的一维数组。 列向量的大小 N,不 Nx1. 例如, 兰德(N)制作1维数组。
*在朱莉娅, [x,y,z] 将始终构造一个包含 x, y 和 z.
**要在第一个("垂直")维度中连接,请使用 xref:base/arrays.adoc#Base.vcat[`vcat(x,y,z)`]或用分号分隔(`[x;y;z]`).
**要在第二个("水平")维度中连接,请使用 xref:base/arrays.adoc#Base.hcat[`hcat(x,y,z)`]或用空格分隔(`[x y z]`).
**要构造块矩阵(在前两个维度中串联),请使用 xref:base/arrays.adoc#Base.hvcat[`[医]hvcat`]或组合空格和分号(`[a b;c d]`).
*在朱莉娅, a:b 和 a:b:c 建造工程 抽象,抽象 物体。 要像在MATLAB中那样构造一个完整的向量,请使用 收集(a:b). 一般不需要打电话 收集资料 不过。 一个 抽象,抽象 在大多数情况下,object将像普通数组一样工作,但效率更高,因为它会懒惰地计算其值。 这种创建专门对象而不是完整数组的模式经常被使用,并且在诸如 范围,或与迭代器如 枚举,而 拉链. 特殊对象主要可以像普通数组一样使用。
*Julia中的函数返回其最后一个表达式或 回来吧 关键字,而不是在函数定义中列出要返回的变量的名称(请参阅 返回关键字的详细信息)。
*Julia脚本可以包含任意数量的函数,并且所有定义在加载文件时都是外部可见的。 函数定义可以从当前工作目录之外的文件加载。
*在Julia中,必须使用括号来调用零参数的函数,如 兰德().
*在Julia中,当您要将标量值函数elementwise应用于数组时,请使用广播语法: f.(A) 而不是 f(A). 在某些情况下,这两个操作都是定义的,但意味着不同的东西:在MATLAB中 高级(A) 应用元素和 expm(A) 是https://en.wikipedia.org/wiki/Matrix_exponential[矩阵指数],但在Julia exp。(一) 应用元素和 高级行政主任(A) 是矩阵指数。
*
+
在朱莉娅,运营商 |
),以及 |
*在Julia中,可以使用splat运算符将集合的元素作为参数传递给函数 ...,如在 xs=[1,2];f(xs。..).
*朱莉娅的 svd将奇异值作为向量返回,而不是作为密集对角矩阵返回。
*在朱莉娅, ... 不用于继续代码行。 相反,不完整的表达式会自动继续到下一行。
*在Julia和MATLAB中,变量 ans 设置为交互式会话中发出的最后一个表达式的值。 在Julia中,与MATLAB不同, ans 在非交互模式下运行Julia代码时不设置。
*朱莉娅的 结构体s不支持在运行时动态添加字段,不像MATLAB的 班级es. 相反,使用 Dict. 朱莉娅的Dict不是命令。
*在Julia中,每个模块都有自己的全局作用域/命名空间,而在MATLAB中只有一个全局作用域。
*在MATLAB中,删除不需要的值的惯用方法是使用逻辑索引,就像在表达式中一样 x(x>3) 或者在声明中 x(x>3)=[] 要修改 x 到位。 相比之下,Julia提供了更高阶的函数 过滤器和 过滤器!,允许用户写 过滤器(z->z>3,x) 和 过滤器!(z->z>3,x) 作为相应音译的替代 x[x.>3] 和 x=x[x.>3]. 使用 过滤器!减少了临时数组的使用。
*从上一点开始,要替换满足特定条件的值,例如矩阵中所有元素的阈值运算,可以在Matlab中实现,如下所示 A(a<阈值)=0. 茱莉亚的等价物是 A[A.<阈值]。= 0.
*提取(或"取消引用")单元格数组的所有元素的类似物,例如 vertcat(一个{:}) 在MATLAB中,使用Julia中的splat运算符编写,例如 vcat(A...).
*在朱莉娅, [医]附 函数进行共轭转置;在MATLAB中, 伴随,伴随 提供"adjugate"或经典adjoint,这是辅因子矩阵的转置。
*在朱莉娅,一个^b^c被评价为a^(b^c)而在MATLAB中它是(a^b)^c.
与R值得注意的区别
Julia的目标之一是为数据分析和统计编程提供一种有效的语言。 对于来自R的用户来说,这些是一些值得注意的差异:
*Julia的单引号括住字符,而不是字符串。
*Julia可以通过索引成字符串来创建子字符串。 在R中,在创建子字符串之前,必须将字符串转换为字符向量。
*在Julia中,与Python一样,但与R不同,字符串可以用三引号创建 """ ... """. 此语法便于构造包含换行符的字符串。
*在Julia中,使用splat运算符指定varargs ...,它总是遵循一个特定变量的名称,不像R,为其 ... 能孤立地发生。
*在Julia中,模数为 国防部(a,b),不 a%%b. % 在Julia中是余数运算符。
*Julia使用括号构建载体。 朱莉娅的 [1, 2, 3] 是R的等价物 c(1,2,3).
*在Julia中,并非所有数据结构都支持逻辑索引。 此外,Julia中的逻辑索引仅支持长度等于被索引对象的向量。 例如:
**在R, `c(1, 2, 3, 4)[c(真,假)]` 相当于 `c(1,3)`. **在R, `c(1, 2, 3, 4)[c(真,假,真,假)]` 相当于 `c(1,3)`.
**在朱莉娅, `[1, 2, 3, 4][[真,假]]` 抛出一个 xref:base/base.adoc#Core.BoundsError[`BoundsError`].
**在朱莉娅, `[1, 2, 3, 4][[真,假,真,假]]` 生产 `[1, 3]`.
*像许多语言一样,Julia并不总是允许对不同长度的向量进行操作,不像r,其中向量只需要共享一个共同的索引范围。 例如, c(1, 2, 3, 4) + c(1,2) 是有效的R,但等价的 [1, 2, 3, 4] + [1, 2] 会在Julia中抛出一个错误。
*当逗号不改变代码的含义时,Julia允许一个可选的尾随逗号。 当索引到数组时,这可能会导致R用户混淆。 例如, x[1,] 在R中返回矩阵的第一行;然而,在Julia中,逗号被忽略,因此 x[1,]==x[1],并将返回第一个元素。 要提取行,请务必使用 :,如在 x[1,:].
*朱莉娅的 地图先取函数,然后取其参数,不像 lapply(<结构>,函数,...) 在R.类似的朱莉娅相当于 apply(X,MARGIN,FUN,...) 在R是 地图单其中函数是第一个参数。
*多变量应用于R,例如 mapply(选择,11:13,1:3),可以写成 广播(二项,11:13,1:3) 在朱莉娅。 等效地,Julia为矢量化函数提供了更短的点语法 二项。(11:13, 1:3).
*朱莉娅使用 结束 表示条件块的结尾,如 如果,循环块,像 而/ 为,和功能。 代替单行 if(cond)语句,Julia允许表单的语句 if cond;语句;结束, cond&&声明 和 !cond//声明. 后两种语法中的赋值语句必须显式包装在括号中,例如 cond&&(x=值).
*在朱莉娅, <-, <<- 和 -> 不是赋值运算符。
*朱莉娅的 -> 创建一个匿名函数。
*朱莉娅的 *运算符可以执行矩阵乘法,不像在R.If A 和 B 是矩阵,则 A*B 表示Julia中的矩阵乘法,相当于R的 A%*%B. 在R中,同样的符号将执行元素明智的(Hadamard)产品。 要获得元素乘法运算,您需要编写 A.*B 在朱莉娅。
*Julia使用 转置,转置 函数和共轭转位使用 ' 操作员或 伴随,伴随 函数。 朱莉娅的 转置(A) 因此相当于R的 t(A). 此外,Julia中的非递归转置由 排列,排列 函数。
*Julia在编写时不需要括号 如果 声明或 为/而 循环:使用 对于我在[1,2,3] 而不是 for(i in c(1,2,3)) 和 如果i==1 而不是 如果(i==1).
*朱莉娅不对待数字 0 和 1 作为布尔值。 你不能写 如果(1) 在朱莉娅,因为 如果 语句只接受布尔值。 相反,你可以写 如果属实, 如果Bool(1),或 如果1==1.
*朱莉娅不提供 nrow 和 ncol. 相反,使用 尺寸(M,1) 为 nrow(米) 和 尺寸(M,2) 为 ncol(米).
*Julia不能赋值给赋值操作左侧函数调用的结果:不能写 diag(M)=填充(1,n).
*Julia不鼓励用函数填充主命名空间。 Julia的大多数统计功能见于https://pkg.julialang.org/[包装]下https://github.com/JuliaStats[JuliaStats组织]。 例如:
**有关概率分布的函数由https://github.com/JuliaStats/Distributions.jl[发行包]。
**Https://github.com/JuliaData/DataFrames.jl[DataFrames包]提供数据帧。
**广义线性模型由https://github.com/JuliaStats/GLM.jl[GLM包]。
*Julia提供元组和真正的哈希表,但不是R风格的列表。 当返回多个项目时,您通常应该使用元组或命名元组:而不是 列表(a=1,b=2),使用 (1, 2) 或 (a=1,b=2).
*Julia鼓励用户编写自己的类型,这比R中的S3或S4对象更容易使用。Julia的多重调度系统意味着 表(x::TypeA) 和 表(x::TypeB) 表现得像R的 表。打字(x) 和 表。打字(x).
*在Julia中,值在分配或传递给函数时不会被复制。 如果函数修改数组,则更改将在调用方中可见。 这与R非常不同,允许新函数更有效地对大型数据结构进行操作。
*在朱莉娅,一个范围像 a:b 不是像R中那样的向量的简写,而是一个专门的 抽象,抽象 用于迭代的对象。 要将范围转换为矢量,请使用 收集(a:b).
* : 运算符在R和Julia中具有不同的优先级。 特别是,在Julia中,算术运算符的优先级高于 : 运算符,而在R中则相反。, 1:n-1 在Julia相当于 1:(n-1) 在R。
*朱莉娅的 总和, prod,prod, 最大值,和 最低限额 它们都接受一个可选的关键字参数 暗淡无光,它表示进行操作的维度。 例如,让 A=[12;34 在朱莉娅和 B<-rbind(c(1,2),c(3,4)) 是R中的相同矩阵。 总和(A) 给出相同的结果 总和(B),但是 总和(A,dims=1) 是一个行向量,包含每列和 总和(A,dims=2) 是包含每行总和的列向量。 这与R的行为形成鲜明对比,其中分离 感冒(B) 和 行(B) 功能提供这些功能。 如果 暗淡无光 关键字参数是一个向量,然后它指定执行求和的所有维度,同时保留求和数组的维度,例如 sum(A,dims=(1,2))==hcat(10). 应该注意的是,没有关于第二个参数的错误检查。
*在R中,性能需要矢量化。 在Julia中,情况正好相反:性能最好的代码通常是通过使用devectorized循环来实现的。 *Julia被热切地评估,不支持R风格的懒惰评估。 对于大多数用户来说,这意味着很少有不带引号的表达式或列名。
*朱莉娅不支持 NULL 类型。 最接近的等价物是 什么都没有,但它的行为像一个标量值,而不是像一个列表。 使用方法 x===无 而不是 是。空(x).
*在Julia中,缺失值由 失踪对象而不是由 呐. 使用方法 ismissing(x)(或 ismissing。(x) 于向量上的按元素操作)而不是 is.na(x). 该 跳板,跳板函数一般用来代替 呐.rm=真 (虽然在某些特定情况下,函数需要 跳板,跳板 论证)。
*Julia缺少R的等价物 分配;分配 或 获取.
*在朱莉娅, 回来吧 不需要括号。
与Python值得注意的区别
*朱莉娅的 为, 如果, 而 等。 块由终止 结束 关键字。 缩进级别并不像在Python中那样重要。 与Python不同,Julia没有 通行证 关键字。
*字符串用双引号表示("文本")在Julia中(用三个双引号表示多行字符串),而在Python中,它们可以用单引号表示('文本')或双引号("文本"). 单引号用于Julia中的字符('c').
*字符串连接是用 * 在朱莉娅,不是 + 就像在Python中一样。 类似地,字符串重复是用 ^,不 *. 字符串字面量的隐式字符串连接,如在Python中(例如 'ab''cd'=='abcd')不是在朱莉娅完成的。
*Python列表-灵活但缓慢-对应于Julia 向量{Any} 型或更一般 向量{T} 哪里 T 是一些非混凝土元素类型。 像NumPy数组这样的"快速"数组,可以就地存储元素(即, dt型,dt型 是 np.漂浮64, [('f1',np.uint64),('f2',np.int32)] 等。)可以用 数组{T} 哪里 T 是一个具体的、不可变的元素类型。 这包括内置类型,如 漂浮64, Int32, Int64 但也更复杂的类型,如 元组{UInt64,Float64} 还有许多用户定义的类型。
*在Julia中,数组,字符串等的索引。 是基于1而不是基于0。
*Julia的切片索引包括最后一个元素,与Python中不同。 a[2:3] 在朱莉娅是 a[1:3] 在Python中。
*与Python不同,Julia允许https://julialang.org/blog/2017/04/offset-arrays/[具有任意索引的AbstractArrays]。 Python对负索引的特殊解释, a[-1] 和 a[-2],应该写 a[完] 和 a[结束-1] 在朱莉娅。
*朱莉娅要求 结束 用于索引,直到最后一个元素。 x[2:结束] 在Julia相当于 x[1:] 在Python中。
*在朱莉娅, : 在任何对象创建一个 符号或_quotes_一个表达式;所以, x[:5] 是一样的 x[5]. 如果你想得到第一个 n 数组的元素,然后使用范围索引。
*Julia的范围索引格式为 x[开始:步骤:停止],而Python的格式是 x[开始:(停止+1):步骤]. 因此, x[0:10:2] 在Python中相当于 x[1:2:10] 在朱莉娅。 同样地, x[::-1] 在Python中,它指的是反向数组,相当于 x[结束:-1:1] 在朱莉娅。
*在Julia中,范围可以独立构造为 开始:步骤:停止,它在数组索引中使用的语法相同。 该 范围 功能也支持。
*在Julia中,用数组索引矩阵,如 X[[1,2],[1,3]] 指包含第一行和第二行与第一列和第三列的交点的子矩阵。 在Python中, X[[1,2],[1,3]] 指包含cell值的向量 [1,1] 和 [2,3] 在矩阵中。 X[[1,2],[1,3]] 在朱莉娅等同于 X[np.ix_([0,1],[0,2])] 在Python中。 X[[0,1],[0,2]] 在Python中与 X[[CartesianIndex(1,1),CartesianIndex(2,3)]] 在朱莉娅。
*Julia没有行延续语法:如果在一行末尾,输入到目前为止是一个完整的表达式,则认为它已完成;否则输入将继续。 强制表达式继续的一种方法是将其包装在括号中。
*Julia数组是列主(Fortran-ordered),而NumPy数组默认是行主(C-ordered)。 为了在数组上循环时获得最佳性能,循环的顺序应该在Julia中相对于NumPy颠倒(请参阅 性能提示的相关部分)。
*Julia的更新操作符(例如 +=, -=, …)是_not in-place_,而NumPy的是。 这意味着 A=[1,1];B=A;B+=[3,3] 不会更改 A,而是重新绑定名称 B 到右手边的结果 B=B+3,这是一个新的数组。 对于就地操作,使用 B.+= 3 (另见 点运算符),显式循环或 InplaceOps。jl.
*Julia每次调用方法时都会计算函数参数的默认值,这与Python中定义函数时仅计算一次默认值不同。 例如,函数 f(x=rand())=x 每次无参数调用时返回一个新的随机数。 另一方面,功能 g(x=[1,2])=推!(x,3) 申报表 [1,2,3] 每次它被称为 g().
*在Julia中,关键字参数必须使用关键字传递,不像Python中通常可以正向传递它们。 尝试传递关键字参数会改变方法签名,导致 方法;方法 或者调用错误的方法。
*在朱莉娅 % 是余数运算符,而在Python中它是模数。
*在Julia中,常用的 Int型 type对应机器整型(Int32 或 Int64),不像在Python中,其中 int型 是任意长度的整数。 这意味着在朱莉娅 Int型 型会溢出,使得 2^64 == 0. 如果您需要更大的值,请使用其他适当的类型,例如 Int128, 比金特或浮点类型,如 漂浮64.
*虚数单位 sqrt(-1) 在Julia中表示为 我,不 j 就像在Python中一样。
*在Julia中,指数运算符为 ^,不 ** 就像在Python中一样。
*朱莉娅使用 什么都没有 类型 什么都没有 表示空值,而Python使用 无 类型 非类型.
*在Julia中,矩阵类型的标准运算符是矩阵运算,而在Python中,标准运算符是元素运算。 当两者兼而有之 A 和 B 是矩阵, A*B 在Julia中执行矩阵乘法,而不是像Python中那样进行元素乘法。 A*B 在朱莉娅等同于 A@B 在Python中,而 A*B 在Python中与 A.*B 在朱莉娅。
*在Julia中,当要将标量值函数elementwise应用于数组时,请使用广播语法: f.(A) 而不是 f(A). 在某些情况下,这两个操作都被定义,但意味着不同的东西: 笨蛋。高级行政主任(A) 应用元素和 希皮。利纳尔格。expm(A) 是https://en.wikipedia.org/wiki/Matrix_exponential[矩阵指数],但在Julia exp。(一) 应用元素和 高级行政主任(A) 是矩阵指数。
*辅助运算符 ' 在Julia中,返回一个向量的邻接(行向量的惰性表示),而转置运算符 .T 在Python中的向量上返回原始向量(非op)。
*在Julia中,一个函数可能包含多个具体实现(称为_methods_),这些实现是通过基于调用的所有参数类型的多个分派来选择的,而Python中的函数只有一个实现,没有多态性(而Python方法调用使用不同的语法,并允许在方法的接收器上进行分派)。
*朱莉娅没有课程。 相反,有结构(可变或不可变),包含数据但没有方法。
*在Python中调用类实例的方法(x=MyClass(*args);x.f(y))对应于Julia中的函数调用,例如 x=MyType(args。..);f(x,y). 一般来说,multiple dispatch比Python类系统更加灵活和强大。
*Julia结构可能只有一个抽象超类型,而Python类可以从一个或多个(抽象或具体)超类继承。
*逻辑Julia程序结构(包和模块)独立于文件结构,而Python代码结构由目录(包)和文件(模块)定义。
*在Julia中,将大型模块的文本拆分为多个文件是惯用的,而不是每个文件引入一个新模块。 代码通过以下方式在主文件中的单个模块中重新组装 包括. 而Python等价物(执行董事)对于这种用途来说并不典型(它会默默地破坏先前的定义),Julia程序被定义为 模块 水平与 使用 或 进口,只会在第一次需要时执行一次-就像 包括 在Python中。 在这些模块中,组成该模块的各个文件被加载 包括 通过按预期顺序列出它们一次。
*三元运算符 x>0? 1 : -1 在Julia中对应于Python中的条件表达式 1如果x>0其他-1.
*在茱莉亚 @ symbol指的是宏,而在Python中它指的是装饰器。
*Julia中的异常处理使用 试试 — 渔获 — 最后,而不是 试试 — 除了 — 最后. 与Python相反,不建议将异常处理用作Julia中正常工作流程的一部分(与Python相比,Julia在普通控制流中更快,但在异常捕获时更慢)。
*在Julia循环很快,由于性能原因,不需要编写"矢量化"代码。
*注意Julia中的非常量全局变量,特别是在紧循环中。 由于您可以在Julia中编写接近金属的代码(与Python不同),因此全局变量的效果可能很大(请参阅 性能提示)。
*在Julia中,舍入和截断是明确的。 Python的 int(3.7) 应该是 楼层(Int,3.7) 或 Int(楼层(3.7)) 并且区别于 圆(Int,3.7). 楼层(x) 和 圆(x) 自己返回一个与 x 而不是总是回来 Int型.
*在Julia中,解析是显式的。 Python的 浮动("3.7") 会是 解析(Float64,"3.7") 在朱莉娅。
*在Python中,大多数值都可以在逻辑上下文中使用(例如 如果"a": 表示执行以下块,并且 如果"": 意味着它不是)。 在Julia中,您需要显式转换为 布尔 (例如 如果"a" 抛出异常)。 如果你想在Julia中测试一个非空字符串,你可以明确地写 如果!isempty(""). 也许令人惊讶的是,在Python中 如果"假" 和 bool("假") 两者都评估为 真的 (因为 "假" 是一个非空字符串);在Julia, 解析(Bool,"false") 申报表 错误.
*在Julia中,大多数代码块都引入了一个新的本地作用域,包括循环和 试试 — 渔获 — 最后. 请注意,comprehensions(列表,生成器等))在Python和Julia中引入一个新的本地范围,而 如果 块不会在两种语言中引入新的本地作用域。
与C/C的显着差异++
*Julia数组用方括号索引,并且可以有多个维度 A[i,j]. 这种语法不仅仅是c/C中引用指针或地址的语法糖++. 见 关于阵列构造的手动条目。
*在Julia中,数组,字符串等的索引。 是基于1而不是基于0。
*Julia数组在分配给另一个变量时不会被复制。 之后 A=B,改变元素 B 会修改 A ""好吧。 更新操作符,如 += 不就地操作,它们相当于 A=A+B 它将左手侧重新绑定到右手侧表达式的结果。
*Julia数组是列主(Fortran有序),而C/C++ 默认情况下,数组是按行排序的。 为了在数组上循环时获得最佳性能,循环的顺序应该在Julia中相对于C/C颠倒++ (见 性能提示的相关部分)。
*Julia值在分配或传递给函数时不会被复制。 如果函数修改数组,则更改将在调用方中可见。
*在Julia中,空白是显着的,不像C/C++,所以在Julia程序中添加/删除空格时必须小心。
*在Julia中,没有小数点的文字数字(如 42)创建有符号整数,类型 Int型,但文字太大而不适合机器字大小将自动提升为更大的大小类型,例如 Int64 (如果 Int型 是 Int32), Int128,或任意大 比金特 类型。 没有数字文字后缀,例如 L, LL, U, UL认证, ULL,ULL 以指示无符号和/或有符号与无符号。 十进制文字总是有符号的,十六进制文字(以 0x 像C/C++),是无符号的,除非当它们编码超过128位时,在这种情况下它们是类型的 比金特. 十六进制文字也不同于C/C++/Java与Julia中的十进制字面量不同,具有基于字面量的_length_的类型,包括前导0。例如, 0x0 和 0x00 有类型 UInt8, 0x000 和 0x0000 有类型 UInt16,那么具有5到8个十六进制数字的文字具有类型 UInt32,9至16位十六进制数字类型 UInt64,17至32位十六进制数字类型 UInt128,以及更多的32个十六进制数字类型 比金特. 在定义十六进制掩码时需要考虑到这一点,例如 ~0xf==0xf0 与…… ~0x000f==0xfff0. 64位 漂浮64 和32位 漂浮物32位字面量表示为 1.0 和 1.0f0 分别。 浮点文字是四舍五入的(而不是提升为 大块头,大块头 型),如果它们不能被精确地表示。 浮点文字在行为上更接近C/C++. 八进制(前缀为 0o)和二进制(前缀为 0b)文字也被视为无符号(或 比金特 为超过128位)。
*索引 阵列 使用浮点类型通常是Julia中的错误。 C表达式的Julia等价物 a[i/2] 是 a[i>2+1],在哪里 i 是整数类型。
*字符串文字可以用任意一种分隔 " 或 """, """ 分隔文字可以包含 " 没有引用它的字符 "\"". 字符串字面量可以具有内插到它们中的其他变量或表达式的值,由 $变量名 或 $(表达),它在函数的上下文中计算变量名或表达式。
* // 表示a 理性的数字,而不是单行注释(这是 # 在朱莉娅)
* #= 指示多行注释的开始,以及 =# 结束它。
*Julia中的函数返回其最后一个表达式或 回来吧 关键字。 可以从函数返回多个值并将其分配为元组,例如 (a,b)=myfunction() 或 a,b=myfunction(),而不必像在C/C中那样传递指向值的指针++ (即 a=myfunction(&b;).
*Julia不需要使用分号来结束语句。 表达式的结果不会自动打印(除了在交互式提示符,即REPL),并且代码行不需要以分号结尾。 打印,打印或 @printf可用于打印特定输出。 在REPL, ; 可用于抑制输出。 ; 内也有不同的含义 [ ],需要注意的事情。 ; 可用于在单行上分离表达式,但在许多情况下并不是绝对必要的,并且更有助于可读性。
*Julia有两个右移运算符, >> 和 >>>. >> 执行算术移位, >>> 总是执行逻辑移位,不像C/C++,其中的含义 >> 取决于被移位的值的类型。
*朱莉娅的 -> 创建一个匿名函数,它不通过指针访问成员。
*Julia在编写时不需要括号 如果 声明或 为/而 循环:使用 对于我在[1,2,3] 而不是 传递:c[for(int i=1;i⇐3;i++)] 和 如果i==1 而不是 如果(i==1).
*朱莉娅不对待数字 0 和 1 作为布尔值。 你不能写 如果(1) 在朱莉娅,因为 如果 语句只接受布尔值。 相反,你可以写 如果属实, 如果Bool(1),或 如果1==1.
*朱莉娅使用 结束 表示条件块的结尾,如 如果,循环块,像 而/ 为,和功能。 代替单行 if(cond)语句,Julia允许表单的语句 if cond;语句;结束, cond&&声明 和 !cond//声明. 后两种语法中的赋值语句必须显式包装在括号中,例如 cond&&(x=值),因为运算符优先级。
*Julia没有行延续语法:如果在一行末尾,输入到目前为止是一个完整的表达式,则认为它已完成;否则输入将继续。 强制表达式继续的一种方法是将其包装在括号中。
*Julia宏对解析的表达式进行操作,而不是对程序的文本进行操作,这允许它们对Julia代码执行复杂的转换。 宏名称以 @ 字符,并同时具有类似函数的语法, @mymacro(arg1,arg2,arg3),以及类似语句的语法, @mymacro arg1arg2arg3. 这些形式是可以互换的;如果宏出现在另一个表达式中,并且通常是最清晰的,则类似函数的形式特别有用。 类似语句的形式通常用于注释块,如分布式 为 建造工程: @distributed for i in1:n;#=body=#;end. 如果宏构造的结尾可能不清楚,请使用类似函数的形式。
*Julia有一个枚举类型,使用宏表示 @enum(name,value1,value2,...) 例如: @enum(水果,香蕉=1,苹果,梨)
*按照惯例,修改其参数的函数具有 ! 在名称的末尾,例如 推!.
*在C++ 默认情况下,您有静态调度,即您需要将函数注释为虚拟,以便有动态调度。 另一方面,在Julia中,每个方法都是"虚拟的"(尽管它比一般的方法更通用,因为方法是在每个参数类型上调度的,不仅仅是 这,使用最具体的声明规则)。
茱莉亚C/C++:命名空间
*C/C++ 命名空间s大致对应于朱莉娅 模块s.
*Julia中没有私有全局变量或字段。 所有内容都可以通过完全限定的路径(或相对路径,如果需要)公开访问。
* 使用MyNamespace::myfun (C++)大致对应于 导入MyModule:myfun (朱莉娅)。
* 使用命名空间MyNamespace (C++)大致对应于 使用MyModule (朱莉娅)
**在朱莉娅,只有 ``出口``ed符号可供调用模块使用。
**在C{pp},只有在包含的(公共)头文件中找到的元素才可用。
*注意事项: 进口/使用 关键字(Julia)也_load_modules(见下文)。
*注意事项: 进口/使用 (Julia)仅在全局范围级别工作(模块s)
**在C{pp}, `使用命名空间X` 在任意范围内工作(例如:函数范围)。
茱莉亚C/C++:模块加载
*当你想到一个C/C++ "*库*",你很可能正在寻找一个Julia"*包*"。
**注意事项:C/C{pp} 库通常包含多个"软件模块",而Julia"软件包"通常包含一个。
**提醒:朱莉娅 ``模块``s是全局范围(不一定是"软件模块")。 **而不是构建/`使` 脚本*,Julia使用"项目环境"(有时称为"项目"或"环境")。
**构建脚本仅适用于更复杂的应用程序(如需要编译或下载C/C的应用程序){pp} 可执行文件)。
**要在Julia中开发应用程序或项目,您可以将其根目录初始化为"项目环境",并在那里放置特定于应用程序的代码/包。 这提供了对项目依赖性和未来可重复性的良好控制。
**可用的软件包将添加到"项目环境"中,其中包含 `Pkg。添加()` 功能或Pkg REPL模式。 (但是,这不会*加载*所述包)。
**"项目环境"的可用软件包(直接依赖项)列表保存在其 `工程。汤姆尔` 档案。
**"项目环境"的_full_依赖信息是自动生成的并保存在其 `清单。汤姆尔` 档案 `Pkg。解决()`.
*"项目环境"可用的软件包("软件模块")载有 进口 或 使用.
**在C/C{pp},你 `#include<moduleheader>` 获取对象/函数声明,并在构建可执行文件时链接到库中。
**在Julia中,再次调用using/import只是将现有模块带入范围,但不会再次加载它(类似于添加非标准 `#pragma一次` 至C/C{pp}).
**基于目录的包存储库*(Julia)可以通过将存储库路径添加到 基地。LOAD_PATH 阵列。
**基于目录的存储库中的包不需要 `Pkg。添加()` 在被装载之前的工具 `进口` 或 `使用`. 他们只是提供给项目。
**基于目录的软件包存储库是开发本地"软件模块"库的最快解决方案。
茱莉亚C/C++:组装模块
*在C/C++, .c/.cpp 文件被编译并添加到具有构建的库中/使 脚本。
**在朱莉娅, 进口[PkgName]/使用[PkgName] 语句加载 [PkgName]。jl 位于包裹内 [PkgName]/src/ 子目录。
**反过来, `[PkgName]。jl` 通常加载与调用相关联的源文件 `包括"[someotherfile]。jl"`.
* 包括"。/path/to/somefile。jl" (朱莉娅)非常相似 #包括"。/path/to/somefile。jl" (C/C++).
**然而 `+包括"。.."+` (Julia)不用于包含头文件(不是必需的)。
***请勿使用* `+包括"。.."+` (Julia)从其他"软件模块"加载代码(使用 `进口`/`使用` 相反)。
** `包括"path/to/some/module。jl"` (Julia)将在不同的模块中实例化同一代码的多个版本(创建_distinct_类型等)。)与_same_名称)。
** `包括"somefile.jl"` 通常用于在同一个Julia package_("软件模块")中组装多个文件。 因此,确保文件是相对简单的 ``包括``d只有一次(没有 `#ifdef` 混乱)。
茱莉亚C/C++:模块接口
*C++ 使用"public"公开接口 .h/.hpp 文件,而朱莉娅 模块s将针对其用户的特定符号标记为 公众人士或 出口艾迪
**通常情况下,朱莉娅 ``模块``s简单地通过为现有函数生成新的"方法"来添加功能: `基地。推!`).
**因此,Julia软件包的开发人员不能依赖头文件来获取接口文档。
**Julia包的接口通常使用docstrings来描述,README.md,静态网页,。..
*一些开发人员选择不 出口 使用其包/模块所需的所有符号,但仍应将未报告的面向用户的符号标记为 公众人士.
**用户可能需要通过限定函数/结构/来访问这些组件。.. 带有包/模块名称(ex: `+MyModule。run_this_task(。..)+`).
茱莉亚C/C++:快速参考
软件概念 |
朱莉娅 |
C/C++ |
未命名范围 |
|
|
功能范围 |
|
|
全球范围 |
|
|
软件模块 |
一个朱莉娅"包" |
+编译 |
装配+ 软件模块 |
… |
|
进口+ 软件模块 |
|
+连结 |
模块库 |
**自定义软件包注册表 |
更多 +更大的编译 |
*Julia包管理器支持从单个Git存储库注册多个包。
*这允许用户在单个存储库中容纳相关软件包库。
**Julia注册表主要用于提供软件包的版本控制和分发。
**自定义包注册表可用于创建一种类型的模块库。
与Common Lisp值得注意的区别
*Julia默认对数组使用基于1的索引,也可以处理任意 索引偏移。
*函数和变量共享相同的命名空间(“Lisp-1”).
*有一个 对类型,但它并不意味着用作 COMMON-LISP:缺点. 各种可迭代集合可以在语言的大多数部分(例如splatting,元组等)中互换使用。 元组对于异构元素的_short_集合,s是最接近Common Lisp列表的。 使用方法 命名的,命名的s代替alist。 对于同质类型的较大集合, 阵列s和 Dict,Dict应该使用s。
*原型设计的典型Julia工作流程也使用图像的连续操作,使用https://github.com/timholy/Revise.jl[修订.jl]包。
*对于性能,Julia更喜欢操作有 类型稳定性。 在Common Lisp从底层机器操作中抽象出来的地方,Julia更接近它们。 例如:
**整数除法使用 `/` 始终返回浮点结果,即使计算是精确的。
*** `//` 总是返回一个合理的结果
*** `÷` 始终返回(截断)整数结果
**支持Bignums,但转换不是自动的;普通整数 xref:manual/faq.adoc#faq-integer-arithmetic[溢出]。
**支持复数,但要获得复杂的结果, xref:manual/faq.adoc#faq-domain-errors[您需要复杂的输入]。
**有多种复杂和合理类型,具有不同的组件类型。
*模块(命名空间)可以是分层的。 进口和 使用具有双重角色:它们加载代码并使其在命名空间中可用。 进口 因为只有模块名称是可能的(大致相当于 ASDF:LOAD-OP). 插槽名称不需要单独导出。 全局变量不能从模块外部分配给(除了 eval(mod,:(var=val)) 作为逃生舱口)。
*宏开头为 @,并且不像Common Lisp那样无缝地集成到语言中;因此,宏的使用不像后者那样广泛。 卫生的一种形式 宏由语言支持。 由于surface语法不同,因此没有等价于 COMMON-LISP:&BODY;.
*_All_函数是通用的,使用多个调度。 参数列表不必遵循相同的模板,这导致了一个强大的习惯用法(参见 做). 可选参数和关键字参数的处理方式不同。 方法歧义不会像在Common Lisp对象系统中那样得到解决,因此需要为交集定义更具体的方法。
*符号不属于任何包,也不包含任何值_per se_。 M.瓦尔 评估符号 瓦尔 在模块中 M.
*函数式编程风格由语言完全支持,包括闭包,但并不总是Julia的惯用解决方案。 一些 变通方法可能是修改捕获变量时性能所必需的。