Crystal ha un tipo chiamato Nil, che può avere un solo valore: nil.
Serve a rappresentare l'assenza di un valore ed è simile a null o None in altri linguaggi.
I valori di tipo Nil possono essere restituiti da vari metodi, ad esempio String#[]?, che restituisce nil se l'indice è fuori dai limiti.
"foo"[10]? # => nil
Crystal ha quello che è noto come CONTROLLI SUI RIFERIMENTI NULLI, il che significa che tutti i tipi non possono essere nil per impostazione predefinita.
Questo significa che non puoi assegnare nil a una variabile a meno che non la dichiari esplicitamente di tipo Nil.
Di conseguenza, il compilatore controllerà automaticamente i riferimenti nulli.
Si possono adottare diversi approcci per gestire i valori nil.
nil è un valore falsey, così come false.
Questo significa che nelle istruzioni e in altri contesti in cui ci si aspetta un valore falsey o truthy, verrà trattato allo stesso modo di false.
if nil
puts "nil is truthy"
else
puts "nil is falsey"
end
# => nil is falsey
Questo significa che il ramo truthy non verrà eseguito se una variabile che può essere nil ha un valore nil.
foo = "boo"[2]? # It is possible that foo is nil
if foo
p foo.class # => Char
end
Crystal ha un metodo che può essere usato per controllare se un valore è nil.
Si chiama nil? ed è disponibile su tutti gli oggetti.
foo = "boo"[2]?
if foo.nil?
puts "foo is nil"
else
puts "foo is not nil"
end
Questo è un po' diverso quando si usa direttamente il valore in un'istruzione if, perché negli ultimi esempi sia false che nil sarebbero stati trattati come falsi.
Qui solo nil viene trattato come falsey, dato che se fosse stato false non sarebbe stato nil, e quindi sarebbe stato truthy.
Il modo più semplice per gestire i valori nil è assicurarsi che non diventino mai nil fin dall'inizio.
L'operatore or (||) viene spesso usato quando si ha a che fare con Bools, ma, se lo si capisce bene, può essere usato anche per gestire i valori nil.
L'operatore or controlla se il primo valore è truthy; in caso contrario, viene usato il secondo valore.
Si può usare per far sì che, se il valore è nil, venga considerato falsey e quindi venga usato il secondo valore.
"foo"[10]? || "bar" # => "bar"
Vostra Maestà sta organizzando un banchetto nella capitale dell'Unione di Kalmar, Copenaghen. È la festa più importante dell'anno e tutti i nobili sono invitati. Ma in tutto il paese si sta diffondendo la voce che c'è un complotto per avvelenare Vostra Maestà.
Sua Maestà ha chiesto a te, il cercatore reale di veleni, di scoprire se cibo o bevande sono avvelenati. Sua Maestà ha intenzione di servire come cibo solo Mushroom pasties, mentre per bere ci sarà una varietà di bevande.
Se il cibo non è quello che Sua Maestà ha ordinato, è molto probabile che sia avvelenato. Se il cibo non è quello che Sua Maestà ha ordinato, va buttato via.
Implementa il metodo check_food?, che prende l'argomento food, contenente il nome del cibo come String.
Il metodo deve restituire il cibo se è Mushroom pasties; altrimenti deve restituire nil.
CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"
CastleDinner.check_food?("Bread")
# => nil
È possibile che la bevanda sia avvelenata, ma è un po' più difficile capirlo.
La bevanda è avvelenata se non contiene la lettera i nel nome, non importa se maiuscola o minuscola.
Se la bevanda è avvelenata, va buttata via.
Implementa il metodo check_drink?, che prende l'argomento drink, contenente il nome della bevanda come String.
Il metodo deve restituire la bevanda se non è avvelenata, altrimenti deve restituire nil.
CastleDinner.check_drink?("Apple juice")
# => "Apple juice"
CastleDinner.check_drink?("Tea")
# => nil
Sua Maestà non vorrebbe che i suoi ospiti si preoccupassero per il veleno nel cibo. Perciò, se la bevanda è avvelenata, va sostituita con una nuova bevanda, in particolare Apple juice.
Implementa il metodo replace_drink, che prende l'argomento drink, contenente il nome della bevanda come String.
Il metodo deve restituire la bevanda se non è avvelenata, altrimenti deve restituire "Apple juice".
CastleDinner.replace_drink("Orange juice")
# => "Orange juice"
CastleDinner.replace_drink("Tea")
# => "Apple juice"
Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.