朱莉娅:语言特征
本文是Julia语言基础知识的简明指南,基于"最小理论-最大实践"的原则。"所有的材料都是围绕代码组织的:每个部分都用直接工作的例子说明,文本解释保持在必要的最低限度。 这种方法可以让你快速沉浸在语法中,看到典型的结构,并立即开始试验,而不会被冗长的描述分散注意力。 Julia以其表现力和速度而闻名,最好通过live code了解她—这正是拟议选择提供的机会。 在这里,您将找到使用变量、数据类型、集合、函数、多个调度和其他关键语言特性的示例。
变量和赋值
分配整数
x = 100
在表达式中使用变量
x * 5
重新分配变量
x = 10 + 10
Julia是一种动态类型语言,变量可以改变其类型。
x = "Hello World!"
赋值返回右侧的值
b=4
a = (b = 2 + 2) * 5
赋值链也是可能的,在下面的示例中,所有三个变量都被赋值为10
x = y = z = 10
变量名支持Unicode
x1=100
● = "点"
δ = 0.001
案例依赖性,myvar和myVar是两个不同的变量。
myvar = 1
MyVar = 2
变量的禁止名称:
*不能以数字开头:1x=100
*语言函数不能用作变量:baremodule,begin,break,catch,const,continue,do,elseif,end,export,false,finally,for,function,global,if,import,let,local,macro,module,quote,return,struct,true,try,using,while
可变类型(数组)的行为
重要提示:赋值不会为可变对象创建副本!
a = [1, 2, 3]
b引用与a相同的数组
b = a
我们通过a变异数组并输出b,b也看到了变化!
a[1] = 42
b
重新连接数组
a = [1, 2, 3]
b = a
a = 3.14159
b
a = [1, 2, 3]
b .= a
a = [1, 2, 30]
b
数据类型和注释
自动类型检测,Float64是浮点数的默认类型
x = -2.0
typeof(x)
Int64是整数的默认类型。
x = 2
typeof(x)
x = -2
typeof(x)
没有复数的域错误
# sqrt(x) #ERROR
复杂类型的显式指示。 为复杂类型添加0im
x = -2.0 + 0im
typeof(x)
sqrt(x)
类型的注释运算符 :: 检查语句"是否是给定类型的实例"。
(2 + 2)::Int
# (2 + 2)::AbstractFloat #ERROR
(2.0 + 2.0)::AbstractFloat
类型稳定性检查
function fast_sum(arr::Vector{Int})
s = 0
for x in arr
s += x
end
return s
end
@code_warntype fast_sum([1,2,3]) # 应显示Any::Any(或特定类型)
# @code_native fast_sum([1,2,3])#汇编代码
声明变量类型
x = Complex(-2)
typeof(x)
sqrt(x)
类型的层次结构:
*Int64<:Integer<:Real<:Number<:Any
*Float64<:AbstractFloat<:Real<:Number<:Any
参数类型
二维Int64阵列
Array{Int64, 2}
Float64矢量(一维)
Array{Float64, 1}
整数
系统类型的别名:
Int-Int64整数
UInt-UInt64无符号整数
10
前导零不使数字八进制。
0123456789
支持大数自动位深度扩展。
typeof(10000000000000000000)
typeof(1000000000000000000000000000000000000000)
无符号整数(十六进制),大小由位数自动决定。
x = 0x1 # UInt8(1字节)
x = 0x123 # UInt16(2字节)
x = 0x1234567 # UInt32(4字节)
x = 0x123456789abcdef # UInt64(8字节)
x = 0x11112222333344445555666677778888 # UInt128(16字节)
typeof(0xfffffffffffffffffffffffffffffffff)
Julia默认不检查溢出,这是一种周期性行为。
x = typemax(Int64)
x + 1 # 溢出!
x + 1 == typemin(Int64)
x = typemax(UInt64)
x + 1
x + 1 == typemin(UInt64)
BigInt溢流解决方案
10^19
BigInt(10)^19
浮点数。
1.0 # 标准条目
1. # 您可以省略点后的零。
0.5 # 一个常规分数
.5 # 您可以省略点之前的零。
-1.23 # 否
电子符号
1e10 # 1.0e10 = 1.0 × 10^10
2.5e-4 # 0.00025
Float32可以使用后缀f指定
x = 0.5f0
typeof(x)
2.5f-4
Float16是通过显式类型赋值实现的
Float16(4.)
位表示。
0.0 == -0.0
bitstring(0.0)
bitstring(-0.0)
BigFloat的任意精度
BigFloat(2.0)^100 / 4
特殊值
*-Inf(负无穷大)
*Inf(正无穷大)
typemin(Float64)
typemax(Float64)
无穷无尽的算术
1 / 0 # Inf
-5 / 0 # -Inf
0 / 0 # NaN
1 / Inf # 0.0
1 / -Inf # -0.0
Inf - Inf # NaN
0 * Inf # NaN
南不等于自己
NaN == NaN # false!
NaN != NaN # true
NaN < NaN # false
NaN > NaN # false
为了进行正确的比较,它被使用 isequal
isequal(NaN, NaN) # true-NaN被认为是相等的
isequal([1 NaN], [1 NaN]) # true-比较数组
isequal(-0.0, 0.0) # false-区分有符号的零!
机器epsilon
eps(Float64)
eps(1000.)
eps(0.0) # 5.0e-324-最小正数
字符串和符号
线条
s = "Hello!"
插值法
"插值:$s"
"表达式:∞(2+2)"
字符串(不处理转义)
"没有\n插值的字符串"
多线线路
multiline = """
行
带连字符
"""
串联和重复
"Hello" * " " * "World"
"Hi"^3
字符(Char)
c = 'a'
typeof(c)
c+1
符号(Symbol)
sym = :my_symbol
typeof(sym)
它们通常用作字典键。
Dict(:key => "value")
结构和抽象类型
它们用于创建自定义类型和组织层次结构。
# 不可变结构
struct Point
x::Float64
y::Float64
end
# 可变结构
mutable struct MPoint
x::Float64
y::Float64
end
# 抽象类型
abstract type Shape end
struct Circle <: Shape
radius::Float64
end
struct Rectangle <: Shape
width::Float64
height::Float64
end
# 构造函数
Point(3.0, 4.0) # 自动的
馆藏资料
元组是一种不可变的结构,比数组工作得更快。
t = (1, 2, 3)
t[1]
# t[1] = 5 #ERROR
解包元组
a, b, c = t
字典(字典)
d = Dict("a" => 1, "b" => 2)
d["a"]
d["c"] = 3
haskey(d, "a")
keys(d), values(d)
集(Set)-删除重复项
s = Set([1, 2, 2, 3])
1 ∈ s
push!(s, 4)
失踪,一无所有
nothing是null/None的模拟(值缺失)
function f()
return nothing
end
f() === nothing
missing-缺失数据(分布在计算中)
1 + missing
# mean([1, missing, 3]) #ERROR
支票
ismissing(missing)
isnothing(nothing)
基本运算符
算术运算符
1 + 10 - 5 # 加法和减法
5 * 20 / 10 # 乘法和除法
20 \ 10 # 反向除法(10/20)
3^3 # 指数化
5.5 % -2 # 其余的除法
隐式乘法(数值因子),Julia允许你写2x而不是2*x
x = 3
2x # 隐式乘法
2(x + 1) # 它也适用于括号。
2x^2 # 优先级:高于隐式乘法
2^2x
逻辑运算符
!true # 虚假否定
!false # true
true && true # 真-逻辑和(缩写)
true && false # false
false && false # false
true || true # true-逻辑或(缩写)
true || false # true
false || false # false
按位运算符
~100 # -101-按位表示法(反转)
121 & 232 # 104-按位和
121 | 232 # 249-按位或
121 ⊻ 232 # 145位XOR(Unicode字符!)
xor(121, 232) # 145-通过功能相同
~UInt32(121) # 0xffffff86-保型反演
~UInt8(121) # 0x86也是UInt8结果。
更新运算符(就地)
x = 25
x += 25 # x = x + 25
x *= 2 # x = x * 2
x /= 4 # x = x / 4
x ^= 2 # x = x^2
更新运算符可以更改数据类型。
x = 0x01
typeof(x)
x *= 2
typeof(x)
矢量化
创建矩阵
x = [1 2 3 4 5; 6 7 8 9 10]
操作员 . 逐元素应用操作,以及此运算符创建一个新矩阵。
x.^2
x .+ 1 # 每个元素为+1
x .- 1 # 每个元素为1
x .* 2 # 每个元素*2
x ./ 2 # 每个元素/2
点更新运算符
x = [1 2 3 4 5; 6 7 8 9 10]
通过复盖现有数组x来改变它。
x .+= 1
创建一个新的数组,x不改变
y = x .+ 1
比较运算符
2 == 2.0 # true-不同类型,但值相等
3 == 5 # false
3 != 5 # true
3 < 5 # true
5 > 3 # true
3 <= 3 # true
5 >= 5 # true
浮点数的特点:
*正零等于但不大于负零
*Inf等于本身,最重要的是(NaN除外)
*-Inf等于本身,最少(NaN除外)
*NaN比不上任何东西
Julia还允许您编写数学比较链。
10 < 15 <= 20 < 30 == 30 > 20 >= 10 == 10 < 30 != 5
相当于:
(10 < 15) && (15 <= 20) && (20 < 30) && (30 == 30) && (30 > 20) && (20 >= 10) && (10 == 10) && (10 < 30) && (30 != 5)
点比较
x = [1 2 3 4 5; 6 7 8 9 10]
x .<= 3
1 .< x .< 7
索引化
A = [1 2 3; 4 5 6] # 2×3 Matrix{Int64}
A[1, 2] # 2(第一行,第二列)
A[1, :] # 第一行(1×3)
A[:, 2] # 第二列(2×1)
A[1:2, 1] # 第一列就像一个向量
A[1:2, 1:2] # 2×2子矩阵
从末尾索引
A[1, end] # 第一行的最后一个元素
A[end, 1] # 第一列的最后一个元素
逻辑索引
A[A .> 2] # [4, 5, 6, 3] ( 对齐到一个向量)
操作员优先级
层次结构(从最高到最低):
- 数值系数:2x(高于除^以外的所有二进制系数)
- 指数化:^
- 一元数:+x,-x,√x,。..
- 乘法/除法: *, /, \, ÷, %
- 加法/减法:+, -
- 转变: <<, >>, >>>
- 按位和: &
- 按位异或:⊻
- 按位或:|
- 比较:==,!=, <, <=, >, >=
- 类型语句:<:
- 逻辑和: &&
- 逻辑或:|/
- 管道操作符:/>
- 指派任务: =, +=, -=, 等等。
首先x^2=9,然后2*9
x = 3
2x^2
首先2x=6,然后2^6!
2^2x
控制结构
条件运算符
x = 10
msg = if x > 5
"五个以上"
else
"很少"
end
三元运算符
x > 5 ? "是的" : "非也。"
短路评估(替代if)
x > 0 && println("正") # 如果为true,则执行
x < 0 || println("不是负面的") # 如果第一个为false,则执行
周期:
*有先决条件
*附后记
for i in 1:3
println(i)
end
while x > 0
x -= 1
end
遍历集合
for (i, val) in enumerate(["a", "b", "c"])
println("$i: $val")
end
生成器和理解
数组理解(创建数组)
squares = [x^2 for x in 1:5]
与条件
evens = [x for x in 1:10 if x % 2 == 0]
生成器(懒惰计算,节省内存),不会在内存中创建数组,而是一次迭代一个元素。
gen = (x^2 for x in 1:1000000)
sum(gen)
功能和多种调度
一个简短的音符(一个表达式)
f(x) = x^2 + 1
f(5)
f(1)
经典条目(代码块)
function g(x, y)
return x + y
end
默认参数、键参数
function greet(name; greeting="Hello", punctuation="!")
return "$greeting, $name$punctuation"
end
greet("Engee", greeting="Hi")
匿名函数
h = x -> x^2
h(4)
常用于map、filter:
map(x -> x^2, [1, 2, 3])
多个分派-根据数据类型,同一个函数的行为不同。
say_hello(name::String) = "你好,男人!"
say_hello(name::Symbol) = "你好,机器人:$名称"
say_hello("安娜")
say_hello(:R2D2)
启动计划
将执行该文件
include("example.jl")
REPL模式
主要模式是julia
2+2
参考模式(?)
?sqrt
分组模式(])
]add DataFrames
]status
Shell模式(;)
;ls
宏
宏允许您生成代码和扩展语法;在Julia中,它们通常用于调试,时间测量和优化。
@show 2 + 2 # 输出表达式和结果
@time sleep(0.1) # 测量执行时间
@assert 1 == 1 # 检查病情
macro hello(expr)
quote
println("嗨! 现在就要发生了:")
println(" ", $(string(expr)))
$(esc(expr))
end
end
@hello 2 + 3 * 5
模块和命名空间
module MyModule
export hello, PI
const PI = 3.14
hello() = println("Hello from module")
# 未导出
internal() = println("internal")
end
using .MyModule # 或导入MyModule
hello() # 可供选择
# internal()#错误,未导出
错误处理
try
sqrt(-1)
catch e
println("Caught an error: $e")
finally
println("This always runs")
end
# 错误生成
if x < 0
error("x must be non-negative")
end
# 自定义异常
struct MyError <: Exception
msg::String
end
# throw(MyError("something went wrong")) #ERROR
文件
"""
square(x)
返回数字`x`的平方。
# Arguments
-'x':一个数字(任何数字类型)
# Example
```julia
julia> square(5)
25
"""
square(x) = x^2
结论
你集中展示了Julia的基础知识,重点不是冗长的解释,而是视觉代码片段。 这种风格不仅可以让你了解语言的功能,而且可以立即看到它们的作用,记住语法并理解工作的逻辑。 现在你有一个紧凑的备忘单,你可以在编写自己的程序时返回。