Julia Language
uttryck
Sök…
Introduktion till uttryck
Uttryck är en specifik typ av objekt i Julia. Du kan tänka på ett uttryck som representerar en bit av Julia-koden som ännu inte har utvärderats (dvs exekverad). Det finns då specifika funktioner och operationer, som eval()
som utvärderar uttrycket.
Vi kan till exempel skriva ett manus eller skriva in tolkaren följande: julia> 1 + 1 2
Ett sätt att skapa ett uttryck är med :()
-syntaxen. Till exempel:
julia> MyExpression = :(1+1)
:(1 + 1)
julia> typeof(MyExpression)
Expr
Vi har nu ett Expr
typen Expr
. Har just bildats gör det inte någonting - det sitter bara som alla andra föremål tills det ageras. I det här fallet kan vi utvärdera det uttrycket med eval()
:
julia> eval(MyExpression)
2
Således ser vi att följande två är likvärdiga:
1+1
eval(:(1+1))
Varför skulle vi vilja gå igenom den mycket mer komplicerade syntaxen i eval(:(1+1))
om vi bara vill hitta vad 1 + 1 är lika med? Det grundläggande skälet är att vi kan definiera ett uttryck vid en punkt i vår kod, eventuellt ändra det senare och sedan utvärdera det vid en senare punkt fortfarande. Detta kan potentiellt öppna kraftfulla nya funktioner för Julia-programmeraren. Uttryck är en viktig komponent i metaprogrammering i Julia.
Skapa uttryck
Det finns ett antal olika metoder som kan användas för att skapa samma typ av uttryck. Uttrycket intro nämnde: :()
syntax. Kanske är det bästa stället att börja med strängar. Detta hjälper till att avslöja några av de grundläggande likheterna mellan uttryck och strängar i Julia.
Skapa uttryck från strängen
Från Julia- dokumentationen :
Varje Julia-program börjar livet som en sträng
Med andra ord, alla Julia-skript skrivs helt enkelt i en textfil, som inte är något annat än en teckensträng. På samma sätt är alla Julia-kommandon som ingåtts i en tolk bara en sträng med tecken. Julias roll eller något annat programmeringsspråk är då att tolka och utvärdera strängar av karaktärer på ett logiskt, förutsägbart sätt så att dessa strängar med karaktärer kan användas för att beskriva vad programmeraren vill att datorn ska åstadkomma.
Således är ett sätt att skapa ett uttryck att använda parse()
-funktionen som tillämpas på en sträng. Följande uttryck, när det har utvärderats, tilldelar värdet 2 till symbolen x
.
MyStr = "x = 2"
MyExpr = parse(MyStr)
julia> x
ERROR: UndefVarError: x not defined
eval(MyExpr)
julia> x
2
Skapa uttryck med :()
Syntax
MyExpr2 = :(x = 2)
julia> MyExpr == MyExpr2
true
Observera att med denna syntax behandlar Julia automatiskt namnen på objekt som hänvisar till symboler. Vi kan se detta om vi tittar på args
. (Se Fields of Expression Objects för mer information om args
fältet i ett uttryck.)
julia> MyExpr2.args
2-element Array{Any,1}:
:x
2
Skapa uttryck med Expr()
MyExpr3 = Expr(:(=), :x, 2)
MyExpr3 == MyExpr
Denna syntax är baserad på prefixnotation . Med andra ord är det första argumentet för den angivna Expr()
head
eller prefixet. De återstående är arguments
uttryck. head
bestämmer vilka operationer som ska utföras på argumenten.
Mer information om detta finns i Fields of Expression Objects
När du använder denna syntax är det viktigt att skilja mellan att använda objekt och symboler för objekt. I exemplet ovan tilldelar uttrycket exempelvis värdet 2
till symbolen :x
, en perfekt förnuftig operation. Om vi använde x
själv i ett sådant uttryck, skulle vi få det nonsensiska resultatet:
julia> Expr(:(=), x, 5)
:(2 = 5)
På liknande sätt, om vi undersöker args
ser vi:
julia> Expr(:(=), x, 5).args
2-element Array{Any,1}:
2
5
Således Expr()
funktionen Expr()
samma automatiska omvandling till symboler som :()
-syntaxen för att skapa uttryck.
Skapa uttryck i flera linjer med quote...end
MyQuote =
quote
x = 2
y = 3
end
julia> typeof(MyQuote)
Expr
Observera att med quote...end
vi skapa uttryck som innehåller andra uttryck i deras args
fält:
julia> typeof(MyQuote.args[2])
Expr
Se Fields of Expression Objects för mer args
om detta args
fält.
Mer om att skapa uttryck
Detta exempel ger bara grunderna för att skapa uttryck. Se också till exempel Interpolation och uttryck och uttrycksfält för mer information om att skapa mer komplexa och avancerade uttryck.
Fält för uttrycksobjekt
Som nämnts i Intro to Expressions är uttryck en specifik typ av objekt i Julia. Som sådan har de fält. De två mest använda fälten i ett uttryck är dess head
och dess args
. Tänk till exempel uttrycket
MyExpr3 = Expr(:(=), :x, 2)
diskuteras i Skapa uttryck . Vi kan se head
och args
sätt:
julia> MyExpr3.head
:(=)
julia> MyExpr3.args
2-element Array{Any,1}:
:x
2
Uttryck är baserade på prefixnotation . Som sådan specificerar head
generellt den operation som ska utföras på args
. Huvudet måste vara av Julia-typ Symbol
.
När ett uttryck ska tilldela ett värde (när det utvärderas) kommer det vanligtvis att använda ett huvud av :(=)
. Det finns naturligtvis uppenbara variationer till detta som kan användas, t.ex.:
ex1 = Expr(:(+=), :x, 2)
: kräver uttryckningshuvud
Ett annat vanligt head
för uttryck är :call
. T.ex
ex2 = Expr(:call, :(*), 2, 3)
eval(ex2) ## 6
Efter konventionerna om prefixnotation utvärderas operatörer från vänster till höger. Således betyder detta uttryck här att vi kommer att kalla den funktion som är specificerad på det första elementet i args
på de efterföljande elementen. Vi kan på liknande sätt ha:
julia> ex2a = Expr(:call, :(-), 1, 2, 3)
:(1 - 2 - 3)
Eller andra, potentiellt mer intressanta funktioner, t.ex.
julia> ex2b = Expr(:call, :rand, 2,2)
:(rand(2,2))
julia> eval(ex2b)
2x2 Array{Float64,2}:
0.429397 0.164478
0.104994 0.675745
Automatisk bestämning av head
när du använder :()
notering av uttrycksskapande
Observera att :call
implicit används som huvud i vissa konstruktioner av uttryck, t.ex.
julia> :(x + 2).head
:call
Således, med :()
-syntaxen för att skapa uttryck, kommer Julia att försöka automatiskt bestämma rätt huvud att använda. Liknande:
julia> :(x = 2).head
:(=)
Om du inte är säker på vad rätt huvud att använda för ett uttryck som du bildar använder till exempel Expr()
detta vara ett användbart verktyg för att få tips och idéer om vad du ska använda.
Interpolering och uttryck
Skapa uttryck nämner att uttryck är nära besläktade med strängar. Som sådan är principerna för interpolering inom strängar också relevanta för uttryck. I grundläggande stränginterpolering kan vi till exempel ha något som:
n = 2
julia> MyString = "there are $n ducks"
"there are 2 ducks"
Vi använder $
-tecknet för att infoga värdet på n
i strängen. Vi kan använda samma teknik med uttryck. T.ex
a = 2
ex1 = :(x = 2*$a) ## :(x = 2 * 2)
a = 3
eval(ex1)
x # 4
Kontrast det här:
a = 2
ex2 = :(x = 2*a) # :(x = 2a)
a = 3
eval(ex2)
x # 6
Således, med det första exemplet, sätter vi i förväg värdet på a
som kommer att användas vid den tidpunkt då uttrycket utvärderas. Med det andra exemplet kommer dock Julia-kompilatorn endast att se till a
att hitta dess värde vid utvärderingstillfället för vårt uttryck.
Externa referenser om uttryck
Det finns ett antal användbara webbresurser som kan hjälpa dig att öka din kunskap om uttryck i Julia. Dessa inkluderar:
- Julia Docs - Metaprogrammering
- Wikibooks - Julia Metaprogramming
- Julias makron, uttryck, etc. för och av de förvirrade, av Gray Calhoun
- Julia månad - metaprogrammering, av Andrew Collier
- Symbolisk differentiering i Julia, av John Myles White
SO-inlägg:
- Vad är en "symbol" i Julia? Svar av Stefan Karpinski
- Varför uttrycker julia detta uttryck på detta komplexa sätt?
- Förklaring av Julia-uttrycket interpolationsexempel