Supponi di volere tutti i numeri interi non negativi fino a 1000. Sarebbe assurdo se dovessi digitarli tutti in un array.
Per questo abbiamo il tipo range:
julia> 0:1000
0:1000
julia> typeof(0:1000)
UnitRange{Int64}
Gli intervalli sono molto comuni: non solo per evitarti di digitare, ma anche come tipo restituito dalle funzioni.
Nota che gli intervalli non sono array.
Gli array vengono definiti fin dall'inizio (valutazione «greedy») e richiedono uno spazio proporzionale alla loro lunghezza.
Al contrario, gli intervalli sono solo un insieme di istruzioni per generare una sequenza (valutazione «lazy», ovvero un «iteratore»).
Se ti serve un intervallo come array, usa la funzione collect() per convertirlo:
julia> collect(0:5)
6-element Vector{Int64}:
0
1
2
3
4
5
Se vuoi, puoi usare collect(type, range) per specificare il tipo dell'array di output.
Si può specificare il passo, in questo caso 0.3:
julia> collect(1.0:0.3:2.0)
4-element Vector{Float64}:
1.0
1.3
1.6
1.9
Quindi la sintassi è start:stepsize:stop.
Entrambi i limiti sono inclusivi, come si vede nell'esempio con i numeri interi.
Se il passo non divide esattamente stop - start, l'ultimo elemento eviterà di superare stop.
Per un controllo più fine, usa la funzione Base.range(), che offre diverse altre opzioni.
Anche sequenze non numeriche possono essere usate negli intervalli. L'esempio più semplice sono le lettere ASCII:
julia> 'a':'d'
'a':1:'d'
julia> typeof('a':'d')
StepRange{Char, Int64}
julia> collect('a':'d')
4-element Vector{Char}:
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
Il tipo Char sarà trattato più in dettaglio in un altro concetto.
Per ora, trattali semplicemente come singoli caratteri tra virgolette singole.
Controlla i limiti di un intervallo con first() e last().
Spesso è utile verificare se un determinato valore fa parte di un intervallo.
La funzione sottostante è in(), ma è più comune usare l'operatore infisso in o il suo sinonimo più matematico ∈.
In un editor adatto, la scorciatoia per ∈ è \in e poi tab.
r = 1:10 # => 1:10
first(r) # => 1
last(r) # => 10
7 in r # => true
11 ∈ r # => false
L'operatore in o ∈ qui è usato con gli intervalli, ma può essere usato anche con diversi altri tipi di collezione, come vettori, insiemi e dizionari.
Nell'indicizzazione degli array si possono usare intervalli di numeri interi e array:
nums = collect(10.0:50.0)
nums[3:2:7] # gives [12.0, 14.0, 16.0]
nums[ [3, 5, 7] ] # also gives [12.0, 14.0, 16.0]
Funziona anche l'uso con end, anche se la precedenza degli operatori può rendere necessarie le parentesi:
nums[(end - 3):end]
4-element Vector{Float64}:
47.0
48.0
49.0
50.0
Naturalmente, qualsiasi elemento dell'indice può essere una variabile intera già esistente.