Supponiamo di aver creato le seguenti variabili:
s=John
i=12345
f=3.14
Tutte queste variabili sono archiviate in memoria come stringa o bashhanno altri tipi di dati?
Supponiamo di aver creato le seguenti variabili:
s=John
i=12345
f=3.14
Tutte queste variabili sono archiviate in memoria come stringa o bashhanno altri tipi di dati?
Risposte:
Le variabili di Bash non sono tipizzate .
A differenza di molti altri linguaggi di programmazione, Bash non separa le sue variabili per "tipo". In sostanza, le variabili di Bash sono stringhe di caratteri, ma, a seconda del contesto, Bash consente operazioni aritmetiche e confronti su variabili. Il fattore determinante è se il valore di una variabile contiene solo cifre.
Come dice un'altra risposta , c'è una sorta di forma debole di battitura a macchina declare.
Questa è una forma molto debole della digitazione [1] disponibile in alcuni linguaggi di programmazione.
Vedi un esempio:
declare -i number # The script will treat subsequent occurrences of "number" as an integer. number=3 echo "Number = $number" # Number = 3 number=three echo "Number = $number" # Number = 0 # Tries to evaluate the string "three" as an integer.
Riferimenti:
Bash ha essenzialmente semplici variabili scalari, array e array associativi. Inoltre, gli scalari possono essere etichettati come numeri interi con l' declareintegrato . Dal punto di vista dell'utente del programmatore di script / shell, le variabili stringa fungono da stringhe, le variabili intere fungono da numeri interi e le matrici di conseguenza al loro tipo. L'implementazione interna non è molto rilevante.
Ma, se vogliamo sapere come i dati sono effettivamente archiviati in memoria, dobbiamo esaminare il codice sorgente per vedere cosa fa effettivamente il programma.
In Bash 4.4, gli scalari sono memorizzati come stringhe, indipendentemente dal tag intero. Ciò è visibile nella definizione di struct variable/ SHELL_VARtypedef e nella funzionemake_variable_value , che traduce esplicitamente numeri interi in stringhe per l'archiviazione.
Gli array sono memorizzati in quello che sembra essere un elenco collegato ( array.h) e gli array associativi come tabelle hash. I valori al loro interno vengono nuovamente memorizzati come stringhe. La scelta di un elenco collegato per le matrici può sembrare strana, ma poiché le matrici possono essere sparse e gli indici possono essere numeri arbitrari indipendentemente dal numero di elementi contenuti nell'array, tale scelta di progettazione è un po 'più semplice da comprendere.
Tuttavia, il codice contiene anche una definizione per non utilizzatounion _value , con campi per numeri interi, numeri in virgola mobile e valori di stringa. È contrassegnato in un commento come "per il futuro", quindi è possibile che alcune versioni future di Bash memorizzino diversi tipi di scalari nelle loro forme native.
Per la mia vita non riesco a trovarlo da nessuna parte in così tante parole, ma è così che lo capisco.
Bash è un interprete, non un compilatore e rappresenta tutte le variabili come stringhe. Da qui tutto lo sforzo e l'enfasi che accompagna le espansioni di vario genere.
Bash passa passa tutte le variabili chiamate a declarecome stringhe con gli attributi che controllano come quella variabile deve essere ampliata per declareil magazzinaggio.
banana=yellow #no call to declare
declare -p banana
declare -- banana="yellow" #but declare was invoked with --
declare -i test=a #arithmetic expansion to null/zero
declare -p test
declare -i test="0"
declare -i test2=5+4 #successful arithmetic expansion
declare -p test2
declare -i test2="9"
declare -i float=99.6 #arithmetical expansion fails due to syntax
bash: declare: 99.6: syntax error: invalid arithmetic operator (error token is ".6")
nofloat=99.9
declare -p nofloat
declare -- nofloat"99.6" #Success because arithmetical expansion not invoked
declare -a a #variable is marked as a placeholder to receive an array
declare -p a
declare -a a
a[3]=99 #array elements are appended
a[4]=99
declare -p a
declare -a a=([3]="99" [4]="99")
declare -A newmap #same as -a but names instead of numbers
newmap[name]="A Bloke"
newmap[designation]=CFO
newmap[company]="My Company"
declare -p newmap
declare -A newmap=([company]="My Company" [name]="A Bloke" [designation]="CFO" )
E naturalmente
declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")
La coda di ciò è che anche se declareha una rappresentazione interna che cambia con i flag di attributo, le stringhe sono tutto ciò che bash vede o vuole vedere.
Questa pagina ha una guida completa sulla digitazione delle variabili in Bash. Questa sezione contiene ulteriori informazioni sul declarecomando integrato. Questo frammento di codice da quel link potrebbe essere di interesse:
[bob in ~] declare -i VARIABLE=12
[bob in ~] VARIABLE=string
[bob in ~] echo $VARIABLE
0
[bob in ~] declare -p VARIABLE
declare -i VARIABLE="0"
È irrilevante.
L'unico modo per interagire con le variabili di Bash è tramite Bash, quindi è impossibile per te notare alcuna differenza nel modo in cui le variabili sono archiviate in memoria, perché non puoi mai accedervi direttamente attraverso la memoria , devi sempre chiedere a Bash il loro valore e Bash possono poi tradurli in qualsiasi modo che vuole guardare come se fossero stati conservati in modo specifico.
Infatti, essi non possono neppure essere memorizzati affatto . Non so quanto siano intelligenti le implementazioni comuni di Bash, ma è almeno possibile in casi semplici determinare se una variabile verrà utilizzata e / o se verrà modificata e ottimizzarla completamente o incorporarla.
bash).