In diesem Artikel möchte ich über die leckeren und nützlichen Syntaxbrötchen Julia sprechen, die den bitteren Anteil des Programmierers versüßen sollen.
Gehen!

Infix-Operatoren sind normale Funktionen.
, +
, -
, <
, ==
, in
(&&
||
, .. - "" ), ( ). , .
, :
struct SetOfTwo{T}
a::T
b::T
function SetOfTwo(a::A, b::B) where {A,B}
if a != b
T = promote_type(A, B)
return new{T}(a, b)
else
throw(ArgumentError("Set elements must be distinct"))
end
end
end
:
Base.in(x, s::SetOfTwo) = x == s.a || x == s.b
Base.:(==)(s1::SetOfTwo, s2::SetOfTwo) = (s1.a in s2) && (s1.b in s2)
:
Base.:(==)(s1::SetOfTwo, s2::AbstractSet) = length(s2) == 2 && s1.a in s2 && s1.b in s2
Base.:(==)(s1::AbstractSet, s2::SetOfTwo) = s2 == s1
, , . , , :
julia> ⇒(a::Bool, b::Bool) = b || !a
⇒ (generic function with 1 method)
julia> struct end
julia> = ()
julia> 2 * 2 == 4 ⇒ isa
true
!
: fn
, , !fn
— , .
julia> filter(!ismissing, [1, missing, missing, 3, 5, 8, missing])
4-element Array{Union{Missing, Int64},1}:
1
3
5
8
Julia - for
, . for
— for x in collection ... end
. , . , iterate(collection[, state])
, for
:
for x in collection
...
end
⇓
let iter = iterate(collection)
while !isnothing(iter)
x, state = iter
...
iter = iterate(collection, state)
end
, iterate
nothing
, .
, , foreach
( ), collect
( ), in
( ) . , , . , , — , .
, , Base.Iterators
. — , , , . , , .
Comprehensions
julia> [x for x in 1:3]
3-element Array{Int64,1}:
1
2
3
julia> Float64[x^3 for x in 1:10 if iseven(x)]
5-element Array{Float64,1}:
8.0
64.0
216.0
512.0
1000.0
julia> Dict(string(s) => length(s) for s in split(" "))
Dict{String,Int64} with 6 entries:
"" => 1
"" => 5
"" => 4
"" => 1
"" => 9
"" => 3
-, Python. Python , comprehension' , .
comprehension' — , :
julia> @btime sum([x for x in 1:10])
38.467 ns (1 allocation: 160 bytes)
55
julia> @btime sum(x for x in 1:10)
1.552 ns (0 allocations: 0 bytes)
55
, , , coll
x for x in coll
, — iterate
. .
...
:
julia> min(1, 2, 3)
1
julia> min([1, 2, 3])
ERROR: MethodError: no method matching min(::Array{Int64,1})
...
julia> min([1, 2, 3]...)
1
, . . — , :
julia> range_settings = Dict(:stop => 10, :step => 3)
Dict{Symbol,Int64} with 2 entries:
:stop => 10
:step => 3
julia> range(1, range_settings...)
ERROR: MethodError: no method matching range(::Int64, ::Pair{Symbol,Int64}, ::Pair{Symbol,Int64})
...
— , , . — , . , -:
julia> range_settings = Dict(:stop => 10, :step => 3)
Dict{Symbol,Int64} with 2 entries:
:stop => 10
:step => 3
julia> range(1; range_settings...)
1:3:10
julia> range_settings = [:stop => 10, :step => 3]
2-element Array{Pair{Symbol,Int64},1}:
:stop => 10
:step => 3
julia> range(1; range_settings...)
1:3:10
julia> range_settings = Set(range_settings)
Set{Pair{Symbol,Int64}} with 2 elements:
:step => 3
:stop => 10
julia> range(1; range_settings...)
1:3:10
— . , , , .
julia> range_settings = (stop = 10, step = 3)
(stop = 10, step = 3)
julia> range(1; range_settings...)
1:3:10
— , — , , . :
function crossproduct1(p1::NTuple{3, Real}, p2::NTuple{3, Real})
return p1[2]*p2[3] - p1[3]*p2[2], p1[3]*p2[1] - p1[1]*p2[3], p1[1]*p2[2] - p1[2]*p2[1]
end
function crossproduct2((x1, y1, z1)::NTuple{3, Real}, (x2, y2, z2)::NTuple{3, Real})
return y1 * z2 - y2 * z1, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2
end
Broadcast
broadcasted-, , (loop fusion), ..
- ( / , / , , ) . , broadcast , , . — , "" , . , . "" broadcast(f, collection)
, , broadcast
collection
, .
, broadcast
, . , , , .
julia> parse.(Int, ("3", "14", "15")).^(3, 2, 1)
(27, 196, 15)
julia> (x -> x / 5).(parse.(Float64, ["92", "65", "36"]))
3-element Array{Float64,1}:
18.4
13.0
7.2
julia> parse.(Int, ("3", "14", "15")).^(3, 2, 1) .+ (x -> x / 5).(parse.(Float64, ["92", "65", "36"]))
3-element Array{Float64,1}:
45.4
209.0
22.2
do
: do
- , .
foo(args...) do x
do_something
end
foo(x -> do_something, args...)
?
-, - map
accumulate
:
map(x -> begin
a, b, c = x[1], x[2], x[3]
return a - (b + c) / 2, b - (a + c) / 2, c - (a + b) / 2
end,
[A, B, C])
map([A, B, C]) do x
a, b, c = x[1], x[2], x[3]
return a - (b + c) / 2, b - (a + c) / 2, c - (a + b) / 2
end
-, with ... as ...
Python. , open
, :
open(f -> println(readline(f)), "myfile.txt", "r")
open("myfile.txt", "r") do io
firstline = readline(io)
println(firstline)
end
, open
, , , , :
function open(f::Function, args...)
io = open(args...)
try
f(io)
finally
close(io)
end
end
, — , do
-. , , — , .
, , , .