Όλα όσα πρέπει να γνωρίζετε με αναφορά σε σχέση με την αξία

Όταν πρόκειται για μηχανική λογισμικού, υπάρχουν αρκετές παρεξηγημένες ιδέες και καταχρηστικοί όροι. Με αναφορά σε σχέση με την αξία είναι σίγουρα ένα από αυτά.

Θυμάμαι πίσω την ημέρα που διάβασα το θέμα και κάθε πηγή που πέρασα φάνηκε να έρχεται σε αντίθεση με την προηγούμενη. Χρειάστηκε αρκετός χρόνος για να πάρει μια σταθερή αντίληψη του. Δεν είχα άλλη επιλογή δεδομένου ότι είναι ένα θεμελιώδες θέμα αν είστε μηχανικός λογισμικού.

Έτρεξα σε ένα άσχημο σφάλμα λίγες εβδομάδες πίσω και αποφάσισα να γράψω ένα άρθρο έτσι ώστε άλλοι άνθρωποι να έχουν ευκολότερο χρόνο να υπολογίσουν αυτό το όλο θέμα.

Κωδικοποιώ σε Ruby σε καθημερινή βάση. Επίσης, χρησιμοποιώ το JavaScript αρκετά συχνά, γι 'αυτό και επέλεξα αυτές τις δύο γλώσσες για αυτή την παρουσίαση.

Για να κατανοήσουμε όλες τις έννοιες, θα χρησιμοποιήσουμε και κάποια παραδείγματα Go και Perl.

Για να κατανοήσετε ολόκληρο το θέμα πρέπει να καταλάβετε 3 διαφορετικά πράγματα:

  • Πώς χρησιμοποιούνται οι υποκείμενες δομές δεδομένων στη γλώσσα (αντικείμενα, πρωτόγονοι τύποι, μεταλλαξιμότητα,).
  • Πώς γίνεται η αντιστοίχιση μεταβλητών / αντιγραφής / επανατοποθέτησης / σύγκρισης
  • Πώς μεταβιβάζονται οι μεταβλητές στις λειτουργίες

Υποκείμενοι τύποι δεδομένων

Στο Ruby δεν υπάρχουν πρωτόγονοι τύποι και όλα είναι ένα αντικείμενο που περιλαμβάνει ακέραιους και booleans.

Και ναι υπάρχει ένα TrueClass στο Ruby.

true.is_a (TrueClass) => αληθές
3.is_a; (αληθές) => true
true.is_a (Object) => true
3.is_a? (Object) => true
TrueClass.is_a? (Object) => true
Integer.is_a? (Object) => true

Αυτά τα αντικείμενα μπορούν να είναι είτε μεταβλητά είτε αμετάβλητα.

Αλλοδαπό σημαίνει ότι δεν υπάρχει τρόπος να αλλάξετε το αντικείμενο μόλις δημιουργηθεί. Υπάρχει μόνο μία παράσταση για μια δεδομένη τιμή με ένα αντικείμενο object_id και παραμένει το ίδιο ανεξάρτητα από το τι κάνεις.

Από προεπιλογή, στον Ruby οι αμετάβλητοι τύποι αντικειμένων είναι: Boolean, Numeric, nil και Symbol.

Στη MRI το object_id ενός αντικειμένου είναι το ίδιο με το VALUE που αντιπροσωπεύει το αντικείμενο στο επίπεδο C. Για τα περισσότερα είδη αντικειμένων, αυτό το VALUE είναι ένας δείκτης σε μια θέση στη μνήμη όπου αποθηκεύονται τα πραγματικά δεδομένα αντικειμένου.

Από εδώ και στο εξής θα χρησιμοποιούμε το object_id και τη διεύθυνση μνήμης εναλλακτικά.

Ας τρέξουμε κάποιο κώδικα Ruby στη MRI για ένα αμετάβλητο σύμβολο και ένα μεταβλητό String:

: symbol.object_id => 808668
: symbol.object_id => 808668
'string'.object_id => 70137215233780
'string'.object_id => 70137215215120

Όπως βλέπετε, ενώ η έκδοση του συμβόλου διατηρεί το ίδιο αντικείμενο_id για την ίδια τιμή, οι τιμές των συμβολοσειρών ανήκουν σε διαφορετικές διευθύνσεις μνήμης.

Σε αντίθεση με τον Ruby, το JavaScript έχει πρωτόγονους τύπους.

Είναι - Boolean, null, undefined, String και Number.

Οι υπόλοιποι τύποι δεδομένων πηγαίνουν κάτω από την ομπρέλα των αντικειμένων (Array, Function, and Object). Δεν υπάρχει τίποτα φανταστικό εδώ είναι πολύ πιο απλή από τον Ruby.

[] instanceof Array => true
[] instanceof Object => true
3 instanceof Object => false

Μεταβλητή αντιστοίχιση, αντιγραφή, επανατοποθέτηση και σύγκριση

Στο Ruby κάθε μεταβλητή είναι απλά μια αναφορά σε ένα αντικείμενο (αφού όλα είναι ένα αντικείμενο).

a = 'string'
b = α
# Αν αντιστοιχίζετε a με την ίδια τιμή
a = 'string'
βάζει β => 'string'
βάζει a == b => true # οι τιμές είναι οι ίδιες
βάζει a.object_id == b.object_id => false # adr-s. διαφέρω
# Εάν επανατοποθετήσετε ένα με άλλη τιμή
a = 'νέα συμβολοσειρά'
βάζει a => 'νέα συμβολοσειρά'
βάζει β => 'string'
βάζει ένα == b => false Οι τιμές είναι διαφορετικές
βάζει a.object_id == b.object_id => false # adr-s. διαφέρουν επίσης

Όταν αντιστοιχίζετε μια μεταβλητή, πρόκειται για μια αναφορά σε ένα αντικείμενο όχι το ίδιο το αντικείμενο. Όταν αντιγράφετε ένα αντικείμενο b = a και οι δύο μεταβλητές θα δείχνουν στην ίδια διεύθυνση.

Αυτή η συμπεριφορά ονομάζεται αντιγραφή με βάση την τιμή αναφοράς.

Αυστηρά μιλώντας σε Ruby και JavaScript όλα αντιγράφονται με αξία.

Όταν πρόκειται για αντικείμενα, όμως, οι τιμές είναι οι διευθύνσεις μνήμης αυτών των αντικειμένων. Χάρη σε αυτό μπορούμε να τροποποιήσουμε τιμές που κάθονται σε αυτές τις διευθύνσεις μνήμης. Και πάλι, αυτό ονομάζεται αντίγραφο με βάση την τιμή αναφοράς, αλλά οι περισσότεροι αναφέρονται σε αυτό ως αντίγραφο με παραπομπή.

Θα ήταν αντίγραφο με παραπομπή εάν μετά την εκ νέου ανάθεση σε μια «νέα συμβολοσειρά», το b θα οδηγούσε επίσης στην ίδια διεύθυνση και θα είχε την ίδια τιμή «νέας συμβολοσειράς».

Όταν δηλώνετε b = a, τα a και b δείχνουν την ίδια διεύθυνση μνήμηςΜετά την επανεκχώρηση μιας (a = 'string'), τα a και b δείχνουν διαφορετικές διευθύνσεις μνήμης

Το ίδιο με έναν αμετάβλητο τύπο όπως το Integer:

α = 1
b = α
α = 1
βάζει β => 1
βάζει μια == b => true # σύγκριση με βάση την τιμή
βάζει a.object_id == b.object_id => true # σύγκριση από τη μνήμη adr.

Όταν αναθέτετε έναν στον ίδιο ακέραιο αριθμό, η διεύθυνση μνήμης παραμένει η ίδια, δεδομένου ότι ένας δεδομένος ακέραιος αριθμός έχει πάντα το ίδιο αντικείμενο_δεν.

Όπως βλέπετε όταν συγκρίνετε οποιοδήποτε αντικείμενο με άλλο, συγκρίνεται με τιμή. Αν θέλετε να ελέγξετε εάν είναι το ίδιο αντικείμενο, πρέπει να χρησιμοποιήσετε το object_id.

Ας δούμε την έκδοση JavaScript:

var a = 'συμβολοσειρά'.
var b = a;
α = 'συμβολοσειρά'. Το # a μεταβιβάζεται εκ νέου στην ίδια τιμή
console.log (a); => 'συμβολοσειρά'
console.log (b); => 'συμβολοσειρά'
console.log (α === β); => true // σύγκριση ανά τιμή
var a = [].
var b = a;
console.log (α === β); => true
α = [].
console.log (a); => []
console.log (b); => []
console.log (α === β); => false // σύγκριση ανά διεύθυνση μνήμης

Εκτός από τη σύγκριση - το JavaScript χρησιμοποιεί ως τιμή για πρωτόγονους τύπους και ως αναφορά για αντικείμενα. Η συμπεριφορά φαίνεται να είναι η ίδια ακριβώς όπως και στον Ruby.

Λοιπόν, όχι πολύ.

Οι πρωτεύουσες τιμές στο JavaScript δεν θα μοιράζονται μεταξύ πολλών μεταβλητών. Ακόμα και αν ορίσετε τις μεταβλητές ίσες μεταξύ τους. Κάθε μεταβλητή που αντιπροσωπεύει μια πρωταρχική τιμή εγγυάται ότι ανήκει σε μια μοναδική θέση μνήμης.

Αυτό σημαίνει ότι καμία από τις μεταβλητές δεν θα δείχνει ποτέ στην ίδια διεύθυνση μνήμης. Είναι επίσης σημαντικό ότι η ίδια η τιμή αποθηκεύεται σε μια θέση φυσικής μνήμης.

Στο παράδειγμά μας όταν δηλώνουμε b = a, το b θα δείχνει αμέσως σε μια διαφορετική διεύθυνση μνήμης με την ίδια τιμή 'string'. Επομένως, δεν χρειάζεται να επανατοποθετήσετε ένα για να υποδεικνύετε διαφορετική διεύθυνση μνήμης.

Αυτό ονομάζεται αντιγραφή με τιμή αφού δεν έχετε πρόσβαση στη διεύθυνση μνήμης μόνο στην τιμή.

Όταν δηλώνετε a = b, εκχωρείται με τιμή έτσι ώστε τα a και b να δείχνουν σε διαφορετικές διευθύνσεις μνήμης

Ας δούμε ένα καλύτερο παράδειγμα όπου όλα αυτά έχουν σημασία.

Στο Ruby αν αλλάξουμε την τιμή που βρίσκεται στη διεύθυνση μνήμης τότε όλες οι αναφορές που δείχνουν προς τη διεύθυνση θα έχουν την ίδια ενημερωμένη τιμή:

α = 'χ'
b = α
a.concat ('y')
βάζει a => 'xy'
βάζει β => 'xy'
b.concat ('z')
βάζει a => 'xyz'
βάζει β => 'xyz'
a = 'z'
βάζει a => 'z'
βάζει β => 'xyz'
a [0] = 'y'
βάζει a => 'y'
βάζει β => 'xyz'

Μπορεί να σκεφτείτε στο JavaScript μόνο η τιμή ενός θα αλλάξει αλλά όχι. Δεν μπορείτε να αλλάξετε την αρχική τιμή, καθώς δεν έχετε άμεση πρόσβαση στη διεύθυνση μνήμης.

Θα μπορούσατε να πείτε ότι ορίσατε το 'x' σε ένα αλλά το ανατέθηκε με τιμή, έτσι η διεύθυνση μνήμης του a διατηρεί την τιμή 'x', αλλά δεν μπορείτε να την αλλάξετε, καθώς δεν έχετε καμία αναφορά σε αυτό.

var a = 'x'.
var b = a;
a.concat ('y');
console.log (a); => 'x'
console.log (b); => 'x'
a [0] = 'z'.
console.log (a); => 'x'.

Η συμπεριφορά των αντικειμένων και της υλοποίησης του JavaScript είναι ίδια με τα αντικείμενα με δυνατότητα αλλαγής του Ruby. Και τα δύο αντίγραφα πρέπει να είναι η τιμή αναφοράς.

Οι πρωταρχικοί τύποι JavaScript αντιγράφονται με βάση την τιμή. Η συμπεριφορά είναι ίδια με τα αμετάβλητα αντικείμενα του Ruby, τα οποία αντιγράφονται με βάση την τιμή αναφοράς.

Εσύ;

Και πάλι, όταν αντιγράφετε κάτι από την αξία, αυτό σημαίνει ότι δεν μπορείτε να αλλάξετε (μεταλλάξετε) την αρχική τιμή αφού δεν υπάρχει αναφορά στη διεύθυνση μνήμης. Από την άποψη του κώδικα γραφής, αυτό είναι το ίδιο με το να έχεις αμετάβλητες οντότητες που δεν μπορείς να μεταλλαχθείς.

Αν συγκρίνετε Ruby και JavaScript, ο μόνος τύπος δεδομένων που «συμπεριφέρεται» διαφορετικά από προεπιλογή είναι String (γι 'αυτό χρησιμοποιήσαμε String στα παραπάνω παραδείγματα).

Στο Ruby είναι ένα αντικείμενο με δυνατότητα αλλαγής και αντιγράφεται / διαβιβάζεται από την τιμή αναφοράς ενώ στη JavaScript είναι πρωτόγονος τύπος και αντιγράφεται / περάστηκε από την τιμή.

Όταν θέλετε να κλωνοποιήσετε (όχι αντιγραφή) ένα αντικείμενο, πρέπει να το κάνετε ρητά και στις δύο γλώσσες, ώστε να μπορείτε να βεβαιωθείτε ότι το αρχικό αντικείμενο δεν θα τροποποιηθεί:

a = {'όνομα': 'Kate'}
b = a.clone
b ['όνομα'] = 'Άννα'
βάζει ένα => {: όνομα => "Kate"}
var a = {'όνομα': 'Kate');
var β = {... α}. // με τη νέα σύνταξη ES6
b ['όνομα'] = 'Άννα';
console.log (a); => {όνομα: "Kate"}

Είναι σημαντικό να θυμάστε ότι διαφορετικά θα συναντήσετε κάποια δυσάρεστα σφάλματα όταν επικαλείτε τον κώδικα σας περισσότερες από μία φορές. Ένα καλό παράδειγμα θα ήταν μια αναδρομική λειτουργία όπου χρησιμοποιείτε το αντικείμενο ως επιχείρημα.

Ένα άλλο είναι το React (front-end framework JavaScript), όπου πάντα πρέπει να περάσετε ένα νέο αντικείμενο για την ενημέρωση της κατάστασης, καθώς η σύγκριση λειτουργεί με βάση το αναγνωριστικό αντικειμένου.

Αυτό είναι ταχύτερο επειδή δεν χρειάζεται να περάσετε από τη γραμμή αντικειμένων κατά γραμμή για να δείτε αν έχει αλλάξει.

Πώς μεταβιβάζονται οι μεταβλητές στις λειτουργίες

Η μετάβαση των μεταβλητών στις λειτουργίες λειτουργεί με τον ίδιο τρόπο όπως η αντιγραφή για τους ίδιους τύπους δεδομένων στις περισσότερες γλώσσες.

Στους πρωτότυπους τύπους JavaScript αντιγράφονται και διαβιβάζονται με τιμή και τα αντικείμενα αντιγράφονται και διαβιβάζονται με βάση την τιμή αναφοράς.

Νομίζω ότι αυτός είναι ο λόγος για τον οποίο οι άνθρωποι μιλάνε μόνο για να περάσουν με αξία ή να περάσουν με παραπομπή και ποτέ δεν φαίνεται να αναφέρουν την αντιγραφή. Υποθέτω ότι αναλαμβάνουν την αντιγραφή δουλεύει με τον ίδιο τρόπο.

a = 'b'
def output (string) # πέρασε από την τιμή αναφοράς
  string = 'c' # επανατοποθετηθεί έτσι δεν υπάρχει αναφορά στο πρωτότυπο
  βάζει τη συμβολοσειρά
τέλος
έξοδος (α) => 'c'
βάζει a => 'b'
def output2 (string) # πέρασε από την τιμή αναφοράς
  string.concat ('c') # αλλάζουμε την τιμή που βρίσκεται στη διεύθυνση
  βάζει τη συμβολοσειρά
τέλος
έξοδος (α) => 'bc'
βάζει a => 'bc'

Τώρα στο JavaScript:

var a = 'β'.
έξοδος λειτουργίας (συμβολοσειρά) {// περάσει από την τιμή
  συμβολοσειρά = 'c'; // επανατοποθετείται σε άλλη τιμή
  console.log (συμβολοσειρά);
}}
έξοδος (α); => 'c'
console.log (a); => 'b'
έξοδος συνάρτησης2 (συμβολοσειρά) {// περάσει από την τιμή
  string.concat ('c'); // δεν μπορούμε να το τροποποιήσουμε χωρίς αναφορά
  console.log (συμβολοσειρά);
}}
έξοδος2 (α); => 'b'
console.log (a); => 'b'

Εάν περάσετε ένα αντικείμενο (όχι πρωτόγονο τύπο όπως το κάναμε) στη JavaScript για τη λειτουργία λειτουργεί με τον ίδιο τρόπο όπως το παράδειγμα Ruby.

Άλλες γλώσσες

Έχουμε ήδη δει πώς να αντιγράψετε / περάσουν από την τιμή και να αντιγράψετε / περάσουν από την τιμή αναφοράς. Τώρα θα δούμε τι περνάει με αναφορά και ανακαλύπτουμε επίσης πώς μπορούμε να αλλάξουμε αντικείμενα αν περάσουμε από την αξία.

Όπως έψαχνα για να περάσω από τις γλώσσες αναφοράς δεν μπορούσα να βρω πάρα πολλά και κατέληξα να επιλέξω Perl. Ας δούμε πώς λειτουργεί η αντιγραφή στο Perl:

$ x = 'συμβολοσειρά μου';
$ y = $ x;
$ x = 'νέα συμβολοσειρά';
εκτύπωση "$ x"; => 'νέα συμβολοσειρά'
εκτύπωση "$ y"; => 'συμβολοσειρά'
$ a = {data => "string").
το $ b μου = $ a;
$ a -> {data} = "νέα συμβολοσειρά";
εκτύπωση "$ a -> {data} \ n"; => 'νέα συμβολοσειρά'
εκτύπωση "$ b -> {data} \ n"; => 'νέα συμβολοσειρά'

Λοιπόν αυτό φαίνεται να είναι το ίδιο όπως και στο Ruby. Δεν έχω βρει καμία απόδειξη, αλλά θα έλεγα ότι Perl αντιγράφεται με τιμή αναφοράς για String.

Τώρα ας ελέγξουμε ποιο πέρασμα με αναφορά σημαίνει:

$ x = 'συμβολοσειρά μου';
εκτύπωση "$ x"; => 'συμβολοσειρά'
sub foo {
  $ _ [0] = 'νέα συμβολοσειρά'.
  εκτυπώστε "$ _ [0]"; => 'νέα συμβολοσειρά'
}}
foo ($ x);
εκτύπωση "$ x"; => 'νέα συμβολοσειρά'

Από τη στιγμή που η Perl περνάει με παραπομπή, αν κάνετε μια επανατοποθέτηση στη λειτουργία, θα αλλάξει και η αρχική τιμή της διεύθυνσης μνήμης.

Για να περάσετε από τη γλώσσα αξίας έχω επιλέξει Go όσο σκοπεύω να εμβαθύνω τη γνώση μου Go στο άμεσο μέλλον:

κύριο πακέτο
εισαγωγή "fmt"
function changeAddress (a * int) {
  fmt.Println (α)
  * a = 0 // ορίζοντας την τιμή της διεύθυνσης μνήμης στο 0
}}
functionValue (int) {
  fmt.Println (α)
  a = 0 // αλλάζουμε την τιμή μέσα στη συνάρτηση
  fmt.Println (α)
}}
func main () {
  α: = 5
  fmt.Println (α)
  fmt.Println (& a)
  changeValue (a) // a έχει περάσει από την τιμή
  fmt.Println (α)
  changeAddress (& a) // Η διεύθυνση μνήμης του a περνάει από την τιμή
  fmt.Println (α)
}}
Όταν καταρτίζετε και εκτελείτε τον κώδικα θα λάβετε τα εξής:
0xc42000e328
5
5
0
5
0xc42000e328
0

Αν θέλετε να αλλάξετε την τιμή μιας διεύθυνσης μνήμης, πρέπει να χρησιμοποιήσετε δείκτες και να περάσετε τις διευθύνσεις μνήμης με βάση την τιμή. Ένας δείκτης διατηρεί τη διεύθυνση μνήμης μιας τιμής.

Ο χειριστής & δημιουργεί έναν δείκτη στον τελεστή του και ο τελεστής * υποδηλώνει την υποκείμενη τιμή του δείκτη. Αυτό ουσιαστικά σημαίνει ότι περνάτε τη διεύθυνση μνήμης μιας τιμής με το & και ρυθμίζετε την τιμή μιας διεύθυνσης μνήμης με *.

συμπέρασμα

Πώς να αξιολογήσετε μια γλώσσα:

  1. Κατανοήστε τους υποκείμενους τύπους δεδομένων στη γλώσσα. Διαβάστε μερικές προδιαγραφές και παίξτε μαζί τους. Συνήθως βράζει σε πρωτόγονους τύπους και αντικείμενα. Στη συνέχεια, ελέγξτε εάν τα αντικείμενα αυτά είναι μεταβλητά ή αμετάβλητα. Ορισμένες γλώσσες χρησιμοποιούν διαφορετικές αντιληπτές αντιλήψεις / τακτικές για διαφορετικούς τύπους δεδομένων.
  2. Το επόμενο βήμα είναι η μεταβλητή ανάθεση, αντιγραφή, επανατοποθέτηση και σύγκριση. Αυτό είναι το πιο κρίσιμο μέρος που σκέφτομαι. Μόλις λάβετε αυτό θα είστε σε θέση να καταλάβω τι συμβαίνει. Βοηθάει πολύ αν ελέγξετε τις διευθύνσεις μνήμης κατά την αναπαραγωγή.
  3. Η μετάβαση των μεταβλητών στις λειτουργίες συνήθως δεν είναι ξεχωριστή. Συνήθως λειτουργεί με τον ίδιο τρόπο όπως η αντιγραφή στις περισσότερες γλώσσες. Μόλις καταλάβετε πώς αντιγράφονται και μεταφέρονται οι μεταβλητές, γνωρίζετε ήδη πώς μεταβιβάζονται στις λειτουργίες.

Οι γλώσσες που χρησιμοποιήσαμε εδώ:

  • Go: Αντιγράψτε και περάστε από την τιμή
  • JavaScript: Οι πρωταρχικοί τύποι αντιγράφονται / διαβιβάζονται με βάση την τιμή, τα αντικείμενα αντιγράφονται / διαβιβάζονται από την τιμή αναφοράς
  • Ruby: Αντιγράφηκε και πέρασε από την τιμή αναφοράς + μεταβλητά / αμετάβλητα αντικείμενα
  • Perl: Αντιγράφηκε από την τιμή αναφοράς και πέρασε με αναφορά

Όταν οι άνθρωποι λένε ότι περνούσαν με παραπομπή, συνήθως σημαίνει ότι πέρασαν από την τιμή αναφοράς. Η μετάβαση από την τιμή αναφοράς σημαίνει ότι οι μεταβλητές μεταφέρονται γύρω από την τιμή, αλλά αυτές οι τιμές είναι αναφορές στα αντικείμενα.

Όπως είδατε, ο Ruby χρησιμοποιεί μόνο περάσει από την τιμή αναφοράς ενώ το JavaScript χρησιμοποιεί μια μικτή στρατηγική. Ακόμα, η συμπεριφορά είναι η ίδια για όλους σχεδόν τους τύπους δεδομένων λόγω της διαφορετικής εφαρμογής των δομών δεδομένων.

Οι περισσότερες από τις κύριες γλώσσες είτε αντιγράφονται και διαβιβάζονται με βάση την αξία είτε αντιγράφονται και μεταφέρονται με τιμή αναφοράς. Για τελευταία φορά: Η μετάβαση από την τιμή αναφοράς συνήθως ονομάζεται pass through reference.

Σε γενικές γραμμές, η τιμή περάσματος είναι ασφαλέστερη καθώς δεν θα αντιμετωπίσετε προβλήματα, καθώς δεν μπορείτε να αλλάξετε τυχαία την αρχική τιμή. Είναι επίσης πιο αργό να γράψετε γιατί πρέπει να χρησιμοποιήσετε δείκτες αν θέλετε να αλλάξετε τα αντικείμενα.

Είναι η ίδια ιδέα όπως με τη στατική πληκτρολόγηση έναντι της δυναμικής πληκτρολόγησης - την ταχύτητα ανάπτυξης με το κόστος της ασφάλειας. Όπως υποθέσατε να περάσετε από την αξία είναι συνήθως ένα χαρακτηριστικό των χαμηλότερων επιπέδων γλωσσών όπως C, Java ή Go.

Τα περάσματα με αναφορά ή τιμή αναφοράς χρησιμοποιούνται συνήθως από γλώσσες υψηλότερου επιπέδου όπως JavaScript, Ruby και Python.

Όταν ανακαλύπτετε μια νέα γλώσσα, περάστε τη διαδικασία όπως κάναμε εδώ και θα καταλάβετε πώς λειτουργεί.

Αυτό δεν είναι ένα εύκολο θέμα και δεν είμαι βέβαιος ότι όλα είναι σωστά αυτά που έγραψα εδώ. Εάν νομίζετε ότι έχω κάνει κάποια λάθη σε αυτό το άρθρο, παρακαλώ ενημερώστε με στα σχόλια.