Wait the light to fall

Julia 语言学习笔记

焉知非鱼

Learning Julia

语法 #

数值字面量系数 #

在标识符或圆括号前面直接放一个数字, 例如 2x2(x+y), 会被认为是把标识符和它前面的数字相乘。这样写多项式就很方便了。

向量化的点号运算符 #

[1,2,3] .+ 3

3-element Array{Int64,1}:
 4
 5
 6

.+ 类似于 Raku 中的 »+» 超运算符:

[1,2,3] »+» 3
[4 5 6]

但是 Julia 的 Vectorized "dot" 语法没有 Raku 的超运算符语法清晰。

类似的例子还有:

sin(0.5) # 0.479425538604203

A = [0.5, 1.0, 1.5]
sin.(A)

3-element Array{Float64,1}:
 0.479425538604203
 0.8414709848078965
 0.9974949866040544
f(x,y) = 3x + 4y;
A = [1.0, 2.0, 3.0];
B = [4.0, 5.0, 6.0];
f.(pi, A)
3-element Array{Float64,1}:
 13.42477796076938
 17.42477796076938
 21.42477796076938

f.(A, pi)
3-element Array{Float64,1}:
 15.566370614359172
 18.566370614359172
 21.566370614359172

f.(A,B)
3-element Array{Float64,1}:
 19.0
 26.0
 33.0

等价的 Raku 写法为:

sub f(\x, \y) { 3*x + 4*y};

my \A = [1.0, 2.0, 3.0];
my \B = [4.0, 5.0, 6.0];

A».&f(pi)
[15.566370614359172 18.566370614359172 21.566370614359172]

链式比较 #

1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
true

Raku 同样支持这种链式比较。

虚数 #

real(1 + 2im)         # 1
imag(1 + 2im)         # 2
(1 + 2im) * (1 - 2im) # 5 + 0im
(1 + 2i).re         # 1
(1 + 2i).im         # 2
(1 + 2i) * (1 - 2i) # 5+0i

命名参数 #

function plot(x, y; style="solid", width=1, color="black")
    ###
end

plot(x, y, width=2)
plot(x, y, :width => 2)

函数组合 #

(sqrt  +)(3,6) # 3.0

map(first  reverse  uppercase, split("you can compose functions like this"))
6-element Array{Char,1}:
 'U'
 'N'
 'E'
 'S'
 'E'
 'S'

Piping #

1:10 |> sum |> sqrt # 7.416198487095663

# 等价于
(sqrt  sum)(1:10)  # 7.416198487095663

广播和管道一起使用 #

["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length]
4-element Array{Any,1}:
  "A"
  "tsil"
  "Of"
 7

组合类型 #

  • 不可变组合类型
struct Foo
    bar
    baz::Int
    qux::Float64
end

foo = Foo("rakulang", 6, 1.5)
typeof(foo) # Foo
typeof(Foo) # DataType

foo.bar     # rakulang
foo.qux     # 1.5
foo.qux = 1 # ERROR: setfield! immutable struct of type Foo cannot be changed
  • 可变组合类型
mutable struct Bar
    baz
    qux::Float64
end

bar = Bar("rakudo", 6.0)
bar.baz = 1//2
bar.qux = 2.0

联合类型 #

IntOrString = Union{Int,AbstractString}
1 :: IntOrString          # 1
"rakulang" :: IntOrString # rakulang

参数化类型 #

  • 参数化组合类型
struct Point{T}
    x::T
    y::T
end

point=Point{Float64}(1.0, 2.0)
point.x # 1.0
point.y # 2.0


struct Circle{T,U}
    x::T
    y::U
end

c = Circle{Float64,AbstractString}(6.0, "rakulang")
c.x # 6.0
c.y # rakulang

多重分派 #

f(x::Float64, y::Float64) = 2x + y
f(x::Number, y::Number) = 2x - y

methods(f)
# 2 methods for generic function "f":
[1] f(x::Float64, y::Float64) in Main at REPL[33]:1
[2] f(x::Number, y::Number) in Main at REPL[34]:1

f(2.0, 3.0) # 7
f(2, 3.0)   # 1