Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Θα περίμενε κανείς να βλέπει κώδικα γεμάτος με References αλλά ακόμα περνάνε πίνακες σε συνάρτηση by value.

 

Έχει κάποιο κακό το pass by reference; μήπως δεν συνίσταται σε μικρά δεδομένα; ή μήπως πολύ απλά είναι επειδή δεν έχουμε ακολουθήσει τις αλλαγές στον προγραμματισμό?

  • Απαντ. 31
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Συχνή συμμετοχή στο θέμα

Δημοσ.

Προφανώς μιλάς για γλώσσες υψηλού επιπέδου; Νομίζω τις σχεδίασαν έτσι ώστε να μη χρειάζεται απο τους προγραμματιστες να ασχολούνται με low level optimizations και το workflow τους να μην επηρεάζεται απο το referencing/dereferencing. Σκέψου ότι όσο εντατική χρήση μεταβλητών κι αν κάνεις εφόσον τις ορίζεις και τις δηλωνεις ως τοπικές αυτές "ζούνε" μόνο για ένα συγκεκριμένο διάστημα στο scope τους και κατόπιν γίνονται gc'ed, οπότε δε σπαταλας και πολλή ram.

  • Like 1
Επισκέπτης
Δημοσ.

Γιατί άμα γεμίσεις τον τόπο pass by reference αφενός καταστρέφεις το encapsulation, αφετέρου κάνεις το debug εφιάλτη.

Δημοσ.

Εξαρτάται για ποια γλώσσα μιλάμε. Η Java έχει μόνο "pass by reference". Η Haskell έχει μόνο "pass by value". Η C έχει εμμέσως( με δείκτες ) και τα δύο, ενώ η C++ έχει πράγματι και τα δύο.

 

Δεν έχει νόημα να κάνεις "pass by reference" σε μικρά δεδομένα όπως int, εκτός κ' αν έχεις σοβαρό λόγο. Παρομοίως, δεν έχει νόημα να κάνεις "pass by value" σε μεγάλα δεδομένα όπως structs, classes και arrays.

Δημοσ.

Για παράδειγμα η C#

 

Αρκετός κόσμος δουλεύει με πίνακες/λίστες και δεν χρησιμοποιεί References. Βλέπεις συναρτήσεις του τύπου:

// έστω ότι η συνάρτηση αυτή κάνει χ2 κάθε στοιχείο στη λίστα/πίνακα
private List<MyObject> Multiply(){...}

// θα μπορούσε να είναι έτσι
private void Multiply(ref List<MyObject> list){...}

Σίγουρα το να γεμίσεις το Project με references είναι κακό και χάνεις τον μπούσουλα. Αλλά, έστω στους πίνακες/λίστες βρε παιδί μ.

 

Τέσπα! ούτως η άλλος όταν δουλεύεις με πολύ λίγα δεδομένα δεν σε νοιάζει τίποτα. Ούτε ο χρόνος για να γίνει copy ο πίνακας ούτε τπτ.

Επισκέπτης
Δημοσ.

Και στο παράδειγμα που δίνεις, πιο εύκολο είναι να δω τι επιστρέφει η function κι άρα να καταλάβω τι κάνει, παρά να κάθομαι να κοιτάω τις μεταβλητές. Επίσης, αν θέλω να κάνω μια αλλαγή αλλάζω τον τύπο και είμαι κομπλέ. Αλλά αν είναι by reference θα πρέπει μετά να κάθομαι και να ψάχνω όλα τα σημεία που έχω χρησιμοποιήσει τη μεταβλητή για να δω μην γίνει καμιά στραβή. Δεν μπορώ να φανταστώ πως κάνεις refactoring με pass by reference.

Δημοσ.

Άρα συμπεραίνουμε ότι λόγω της "βαβούρας" χρησιμοποιούμε by value. Και αν πρόκειται για πολλά στοιχεία (επεξεργασία μεγάλων-τεράστιων πινάκων) επιλέγουμε by ref.


Εξαρτάται για ποια γλώσσα μιλάμε. Η Java έχει μόνο "pass by reference"...

 

Ναι! μια φορά είχα κάτι σαν αυτό (δεν το θυμάμαι καλά)

ArrayList<> a;
ArrayList<> b;

a = init();
b = a;
b = edit();

print(a);

και είχαν αλλάξει τα στοιχεία της a λίστας :D. Και έλεγα τι στο πεος γινεται εδω.

Δημοσ.

Η list ειναι οbject. Ολα τα object ειναι reference. Βαζοντας ref απλα κανεις το ref στο reference, ή κατι σα το & στη c++ ή διπλο δεικτη σε c.

Δημοσ.

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

 

Σε όλες τις χρήσιμες γλώσσες μπορείς να πεις αν επιτρέπεται να μεταβληθεί η παράμετρος που περνάς. Δε χρειάζεται καν να κάθεσαι και να τις ελέγχεις, για τη C++ για παράδειγμα, αν ένα reference δεν είναι const υποθέτω ότι πρόκειται να αλλάξει.

Δημοσ.

Για παράδειγμα η C#

 

Αρκετός κόσμος δουλεύει με πίνακες/λίστες και δεν χρησιμοποιεί References. Βλέπεις συναρτήσεις του τύπου:

// έστω ότι η συνάρτηση αυτή κάνει χ2 κάθε στοιχείο στη λίστα/πίνακα
private List<MyObject> Multiply(){...}

// θα μπορούσε να είναι έτσι
private void Multiply(ref List<MyObject> list){...}

 

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

 

Η συνάρτηση που κάνει x2 τα πάντα στη λίστα σε απολύτως καμία περίπτωση δεν πρέπει να παίρνει by-ref, υποθέτω ότι δε λαμβάνεις υπόψη ότι η List είναι ήδη reference type (ή ίσως δεν έχεις υπόψη τη διαφορά value types/reference types).

 

Αν θες γράψε τι ακριβώς νομίζεις ότι θα κέρδιζες με το ref για να τα ξεμπλέξουμε.

Εξαρτάται για ποια γλώσσα μιλάμε. Η Java έχει μόνο "pass by reference".

 

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

 

Η Java έχει μόνο pass by value (δεν έχει ούτε reference types όπως η C++ ούτε ref/out keyword όπως η C#). Απλά, τις περισσότερες φορές (όχι όλες!) αυτό που περνάει by value είναι κάτι που πρακτικά μπορείς να το πεις reference για να συνεννοούμαστε.

  • Like 1
Δημοσ.

Οκ, διόρθωση:

H Java έχει μόνο pass by value, μόνο που το "value" σχεδόν όλων των objects είναι "reference". Αυτό πρακτικά σημαίνει ότι αν προσπαθήσεις να αλλάξεις τη παράμετρο απευθείας( πχ με "a = b;" ) τότε θα αλλάξει μόνο η τοπική μεταβλητή. Αλλά αν αλλάξεις κάποιο από τα μέλη της παραμέτρου(αν έχει) ή αν καλέσεις κάποια μέθοδο της(αν έχει), τότε μπορείς να αλλάξεις την original μεταβλητή. "pass by sharing" και άλλα κουλά...

Δημοσ.

Ναι αυτό με τη λίστα ότι είναι reference type πρόσφατα το έμαθα

 

Δείχνει κάπου/κάπως στα IDE αν ένα Object είναι reference type? 

Δημοσ.

Η σουπερ κλας για ref ειναι object, και για value type, ValueType. Ή αλλιως, η class ειναι object, και το struct ValueType.

Δημοσ.

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

 

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

 

Με αυτόν τον τρόπο μπορείς να περνάς τα πάντα by reference χωρίς πολλά wtf.

Δημοσ.

^ ούτε καν! όταν δουλεύεις με λίστες/πίνακες, και εφόσον το επιτρέπουν οι συνθήκες, το καλύτερο είναι να δουλεύεις πάνω στην υπάρχουσα. Αν γνώμονας μας είναι η απόδοση. Αλλά έχει προχωρήσει τόσο πολύ το hardware που καλύτερα να κάνεις αυτό που λες γιατί σου προσφέρει και καλύτερο έλεγχο κώδικα.

 

 

 

απλά μίλησα και είπα ότι δεν βλέπω κόσμο να κάνει Pass λίστα by ref (ref List<obj> list) ενώ η λίστα είναι ήδη reference type. Και ουσιαστικά με το επιπλέον ref (χωρίς να είμαι σίγουρος) απλά έχουμε reference σε reference.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...