Julia Language
villkors
Sök…
Syntax
- om cond; kropp; slutet
- om cond; kropp; annan; kropp; slutet
- om cond; kropp; annars om cond; kropp; annan; slutet
- om cond; kropp; annars om cond; kropp; slutet
- kond? iftrue: iffalse
- cond && iftrue
- cond || iffalse
- ifelse (cond, iftrue, iffalse)
Anmärkningar
Alla villkorade operatörer och funktioner involverar användning av booleska förhållanden ( true
eller false
). I Julia är typen av booleaner Bool
. Till skillnad från vissa andra språk kan andra typer av nummer (som 1
eller 0
), strängar, matriser och så vidare inte användas direkt i villkor.
Vanligtvis använder man antingen predikatfunktioner (funktioner som returnerar en Bool
) eller jämförelseoperatörer i villkoret för en villkorad operatör eller funktion.
om ... annat uttryck
Det vanligaste villkoret i Julia är uttrycket if
... else
. Nedan implementerar vi till exempel den euklidiska algoritmen för att beräkna den största gemensamma delaren med hjälp av en villkorad för att hantera basfallet:
mygcd(a, b) = if a == 0
abs(b)
else
mygcd(b % a, a)
end
Formen if
... else
i Julia är faktiskt ett uttryck och har ett värde; värdet är uttrycket i svansposition (det vill säga det sista uttrycket) på den gren som tas. Tänk på följande provinmatning:
julia> mygcd(0, -10)
10
Här, a
är 0
och b
är -10
. Villkoret a == 0
är true
, så den första grenen tas. Det returnerade värdet är abs(b)
som är 10
.
julia> mygcd(2, 3)
1
Här a
är 2
och b
är 3
. Villkoret a == 0
är falskt, så den andra grenen tas, och vi beräknar mygcd(b % a, a)
, vilket är mygcd(3 % 2, 2)
. %
-Operatören returnerar resten när 3
är dividerat med 2
, i detta fall 1
. Således beräknar vi mygcd(1, 2)
, och den här gången a
är 1
och b
är 2
. Återigen är a == 0
falsk, så den andra grenen tas, och vi beräknar mygcd(b % a, a)
, vilket är mygcd(0, 1)
. Den här gången är a == 0
äntligen så att abs(b)
returneras, vilket ger resultatet 1
.
om ... annat uttalande
name = readline()
if startswith(name, "A")
println("Your name begins with A.")
else
println("Your name does not begin with A.")
end
Alla uttryck, till exempel if
... else
uttryck, kan sättas i uttalande. Detta ignorerar dess värde men kör fortfarande uttrycket för dess biverkningar.
om uttalande
Liksom alla andra uttryck kan returvärdet för ett if
... else
uttryck ignoreras (och därmed kasseras). Detta är vanligtvis bara användbart när uttryckets kropp har biverkningar, till exempel att skriva till en fil, mutera variabler eller skriva ut på skärmen.
Dessutom är den else
grenen av ett if
... else
uttryck valfritt. Vi kan till exempel skriva följande kod för att mata ut till skärmen endast om ett visst villkor är uppfyllt:
second = Dates.second(now())
if iseven(second)
println("The current second, $second, is even.")
end
I exemplet ovan använder vi tid- och datumfunktioner för att få den aktuella sekunden; om det till exempel är klockan 10:55:27 kommer variabeln second
att hålla 27
. Om detta nummer är jämnt skrivs en rad ut på skärmen. Annars görs ingenting.
Ternary villkorad operatör
pushunique!(A, x) = x in A ? A : push!(A, x)
Den ternära villkorade operatören är ett mindre ordligt if
... else
uttryck.
Syntaxen är specifikt:
[condition] ? [execute if true] : [execute if false]
I det här exemplet lägger vi till x
till samlingen A
endast om x
inte redan finns i A
Annars lämnar vi bara A
oförändrat.
Ternary operator Referenser:
Kortslutningsoperatörer: && och ||
För förgrening
De kortslutna villkorade operatörerna &&
och ||
kan användas som lätta ersättare för följande konstruktioner:
-
x && y
motsvararx ? y : x
-
x || y
motsvararx ? x : y
En användning för kortslutningsoperatörer är som ett mer kortfattat sätt att testa ett tillstånd och utföra en viss åtgärd beroende på det villkoret. Följande kod använder till exempel &&
operatören för att kasta ett fel om argumentet x
är negativt:
function mysqrt(x)
x < 0 && throw(DomainError("x is negative"))
x ^ 0.5
end
Den ||
operatör kan också användas för felkontroll, förutom att det utlöser felet såvida inte ett villkor gäller, i stället för om villkoret har:
function halve(x::Integer)
iseven(x) || throw(DomainError("cannot halve an odd number"))
x ÷ 2
end
En annan användbar applikation av detta är att leverera ett standardvärde till ett objekt, bara om det inte tidigare har definierats:
isdefined(:x) || (x = NEW_VALUE)
Här kontrollerar detta om symbolen x är definierad (dvs om det finns ett värde tilldelat objektet x
). I så fall händer ingenting. Men om inte, kommer x
att tilldelas NEW_VALUE
. Observera att detta exempel bara fungerar inom toppnivån.
Under förhållanden
Operatörerna är också användbara eftersom de kan användas för att testa två villkor, varav den andra endast utvärderas beroende på resultatet av det första villkoret. Från Julia- dokumentationen :
I uttrycket
a && b
utvärderas subexpressionenb
bara oma
utvärderas tilltrue
I uttrycket
a || b
, subexpressionb
utvärderas endast oma
utvärderas tillfalse
Således, medan både a & b
och a && b
kommer att ge true
om både a
och b
är true
, är deras beteende om a
är false
annorlunda.
Anta till exempel att vi vill kontrollera om ett objekt är ett positivt tal, där det är möjligt att det kanske inte ens är ett nummer. Tänk på skillnaderna mellan dessa två försök till implementeringar:
CheckPositive1(x) = (typeof(x)<:Number) & (x > 0) ? true : false
CheckPositive2(x) = (typeof(x)<:Number) && (x > 0) ? true : false
CheckPositive1("a")
CheckPositive2("a")
CheckPositive1()
ger ett fel om en icke-numerisk typ levereras till den som ett argument. Detta beror på att det utvärderar båda uttryck, oavsett resultatet av det första, och det andra uttrycket kommer att ge ett fel när man försöker utvärdera det för en icke-numerisk typ.
CheckPositive2()
ger emellertid false
(snarare än ett fel) om en icke-numerisk typ levereras till den, eftersom det andra uttrycket endast utvärderas om det första är true
.
Mer än en kortslutningsoperatör kan strängas samman. T.ex:
1 > 0 && 2 > 0 && 3 > 5
om uttalande med flera grenar
d = Dates.dayofweek(now())
if d == 7
println("It is Sunday!")
elseif d == 6
println("It is Saturday!")
elseif d == 5
println("Almost the weekend!")
else
println("Not the weekend yet...")
end
Valfritt antal elseif
grenar kan användas med en if
uttalandet, eventuellt med eller utan en slutlig else
gren. Efterföljande villkor utvärderas endast om alla tidigare villkor har visat sig vara false
.
Ifelse-funktionen
shift(x) = ifelse(x > 10, x + 1, x - 1)
Användande:
julia> shift(10)
9
julia> shift(11)
12
julia> shift(-1)
-2
ifelse
funktionen kommer att utvärdera båda grenarna, även den som inte är vald. Detta kan vara användbart antingen när grenarna har biverkningar som måste utvärderas, eller för att det kan vara snabbare om båda grenarna själva är billiga.