Julia 具有强烈的学院派风格,类型系统设计的非常复杂,并且比 C++ 充满历史包袱的类型系统和模板机制精巧很多。

变量作用域

Julia 有相对复杂的作用域机制,包括全局作用域,局部作用域,对于局部作用域又分为软作用域和硬作用域。

大部分语句都会产生作用域,但是有两个例外:begin 语句和 if 语句。

Julia 使用词法作用域,也就是说一个函数的作用域不继承自调用了函数的调用者作用域,而继承自该函数定义处作用域。

容器

元组和具名元组

Julia 支持和 Python 几乎一样的元组,元组中的元素可以是不同类型,例如

1
2
3
4
(1, 2)
1, 2

(1, "2", 3.0)

这里的括号在不存在歧义时可以省略,只含一个元素的元组和空元组有固定的写法,例如

1
2
(1,)
()

元组中的元素可以使用索引访问(索引从1开始),例如

1
2
3
a = (1,'a');
a[1] # 1
a[2] # 'a'

和 Python 一样,Julia 的元组赋值可以自动解包,因此可以用来同时定义多个变量,例如

1
2
3
(x,y,z) = (1,2,3)

x,y,z = 1,2,3

与 Python 相比,Julia 的具名元组在语法上更加方便,例如

1
2
3
a = (x=1, y=2);
a.x # 1
a.y # 2

这看起来非常适合用来打包不可变数据,比字典更加方便。

字典

Julia 的字典也和 Python 差不多,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dic1 = Dict("a" => 1, "b" => 2);

dic1["a"] # 1
dic1["b"] = 100;

length(dic1) # 2
keys(dic1)
# KeySet for a Dict{String, Int64} with 2 entries. Keys:
# "b"
# "a"

values(dic1)
# ValueIterator for a Dict{String, Int64} with 2 entries. Values:
# 100
# 1

字典的索引通常是字符串,但是实际上几乎可以是任何类型。

值得注意的是,在定义字典时使用的键值对并不是特殊语法,而是类似于 C++ 的 std::pair 的数据结构

1
typeof("a"=>2) # Pair{String, Int64}

集合

Julia 的集合语法与 Python 明显不同:

  • Julia 要求集合中的元素必须是同类型的,并且互不相等。(Python 只是要求不可变,用于确保唯一性)
  • Python 支持使用花括号创建集合字面量,Julia 必须使用 Set() 函数

例如

1
2
3
4
5
6
7
8
9
10
11
set1 = Set([1, 2, 3, 2, 3])
# Set{Int64} with 3 elements:
# 2
# 3
# 1

set2 = Set(('a','b','c','a','b','c'))
# Set{Char} with 3 elements:
# 'a'
# 'c'
# 'b'

集合中的元素存储是无序的,可以使用 in 判断元素是否在集合中

1
2
3
set1 = Set([1, 2, 3, 2, 3])

1 in set1 # true

支持集合间的基本运算,包括并集、交集、差集等。

数组

数组是科学计算中的核心容器,Julia 的这部分语法与 Python(Numpy) 和 MATLAB 均有所不同,相关的字面量语法非常混乱(比MATLAB还混乱)

Julia 提供数组来存储有序数据,通常用来存储同一类型的数据,当然也允许混合存储任意类型的数据,但是这会影响数组操作的效率。

TODO