Είναι ένα μεγάλο θέμα! Μπορείς να γράψεις ένα ολόκληρο βιβλίο γι' αυτό, και αρκετοί άνθρωποι το έχουν κάνει (ψάξε στο Amazon για "unicode book" για να δεις μερικά παραδείγματα).
Ο χειρισμός χαρακτήρων στους υπολογιστές ήταν πολύ πιο απλός σε παλαιότερες δεκαετίες, όταν οι προγραμματιστές θεωρούσαν ότι τα αγγλικά ήταν η μόνη σημαντική γλώσσα. Δηλαδή: 26 γράμματα, κεφαλαία και πεζά, 10 ψηφία, μερικά σημεία στίξης, συν έναν κωδικό (0x07) για να χτυπάει ένα κουδούνι, και όλα χωρούσαν σε 7 bits: το σύνολο χαρακτήρων ASCII.
Φυσικά, οι άνθρωποι άρχισαν να ρωτούν τι γίνεται με τα à, ä και Ł, μετά άλλοι άρχισαν να ρωτούν για τα ऄ, ஹ και ญ, και οι νέοι ήθελαν emojis 😱. Τι να κάνουμε;
Για να μην τα πολυλογούμε, πολλοί έξυπνοι και υπομονετικοί άνθρωποι έπρεπε να μετέχουν σε επιτροπές για χρόνια, δουλεύοντας τις λεπτομέρειες του συνόλου χαρακτήρων Unicode και κωδικοποιήσεων όπως το UTF-8, και μεγάλο μέρος του λογισμικού χρειάστηκε μια πολύ περίπλοκη επανεγγραφή. Επίσης, εισήχθησαν πολλά νέα bugs.
Για να μην καταρρεύσουν τα πάντα, ο σχεδιασμός των Unicode/UTF-8 διασφαλίζει ότι οι πρώτοι 127 κωδικοί είναι ίδιοι με το ASCII (ακόμα και το κουδούνι).
Οι γλώσσες που σχεδιάστηκαν μετά το 2005 περίπου έχουν το τεράστιο πλεονέκτημα ότι υπήρχε ήδη ένα αρκετά σταθερό πρότυπο Unicode.
Η Julia (κυκλοφόρησε για πρώτη φορά το 2012) μπόρεσε να υποθέσει ότι τα πάντα θα ήταν Unicode: χαρακτήρες, συμβολοσειρές, ονόματα μεταβλητών και συναρτήσεων, μαθηματικοί τελεστές...
Όπως λέει το εγχειρίδιο, "Η Julia κάνει τον χειρισμό απλού κειμένου ASCII απλό και αποδοτικό, και ο χειρισμός του Unicode είναι όσο πιο απλός και αποδοτικός γίνεται." Πρόσεξε το "όσο πιο ... γίνεται", είναι σημαντικό κομμάτι της δήλωσης.
Τα literals χαρακτήρων γράφονται με μονά εισαγωγικά και είναι διακριτά από τις συμβολοσειρές που γράφονται με διπλά εισαγωγικά.
Αυτό είναι προφανές για όσους προέρχονται από τον κόσμο της C/C++, αλλά μπορεί να μπερδέψει προγραμματιστές Python και Javascript.
julia> a = 'a' # Roman alphabet
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> typeof(a)
Char
julia> jha = 'झ' # Devanagari alphabet
'झ': Unicode U+091D (category Lo: Letter, other)
julia> typeof(jha)
Char
julia> '❤' # heart emoji
'❤': Unicode U+2764 (category So: Symbol, other)
Από τα παραδείγματα βλέπουμε ότι ο τύπος είναι Char, και η Julia έχει περισσότερες πληροφορίες για την κατηγορία του χαρακτήρα.
Κοιτάζοντας πιο προσεκτικά, φαίνεται ότι αυτοί οι χαρακτήρες μπορούν να αναπαρασταθούν με 4 δεκαεξαδικά ψηφία. Το πλήρες σύνολο χαρακτήρων χρειάζεται έως 6 δεκαεξαδικά ψηφία.
Αυτοί οι αριθμοί ονομάζονται "σημεία κώδικα" και προς το παρόν κυμαίνονται από U+0000 έως U+10FFFF.
Εμφανίζονται στο REPL, αλλά μέσα στον κώδικα χρησιμοποίησε τη codepoints() για να τα πάρεις.
Η μετατροπή μεταξύ Char και Int είναι απλή:
julia> Int('a')
97
julia> Char(97)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
Ο μεταγλωττιστής επιτρέπει μερικές μορφές ακέραιης αριθμητικής πάνω σε Char:
julia> 'b' - 'a' # interval, in alphabetic order
1
julia> 'b' + 'a'
ERROR: MethodError: no method matching +(::Char, ::Char)
julia> 'a' + 5
'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)
julia> 'f' + ('A' - 'a') # same as `uppercase('f')`
'F': ASCII/Unicode U+0046 (category Lu: Letter, uppercase)
Πολλές συναρτήσεις χειρισμού συμβολοσειρών μπορούν να δουλέψουν και με είσοδο Char.
uppercase() και lowercase().isuppercase() και islowercase().isletter() καλύπτει πολλά αλφάβηταisdigit(), ελέγχει αυστηρά για 0:9isnumeric(), πιο ευρεία από την isdigit, οπότε true για το ¾ και διάφορα μη ευρωπαϊκά συστήματα γραφήςisxdigit(), δεκαεξαδικά ψηφίαisascii(), χαρακτήρας πριν από το Unicodeispunct(), σημεία στίξηςisspace(), οποιοσδήποτε χαρακτήρας κενούisprint(), εκτυπώσιμοι χαρακτήρες (το αντίθετο είναι η iscntrl())islowercase('A') # false
uppercase('γ') # 'Γ': Unicode U+0393 (category Lu: Letter, uppercase)
ispunct('@') # true
isdigit('A') # false
isxdigit('A') # true
Για τη μετατροπή από συμβολοσειρά σε Char Vector, μπορούμε να χρησιμοποιήσουμε τη collect().
Για τη μετατροπή από Char Vector σε συμβολοσειρά, υπάρχει ο κατασκευαστής String().
julia> s = "abcde"
"abcde"
julia> cv = collect(s)
5-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)
'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
julia> String(cv)
"abcde"
Αυτό λειτουργεί με οποιουσδήποτε χαρακτήρες, όχι μόνο με ASCII.
julia> collect("❤,😱")
3-element Vector{Char}:
'❤': Unicode U+2764 (category So: Symbol, other)
',': ASCII/Unicode U+002C (category Po: Punctuation, other)
'😱': Unicode U+1F631 (category So: Symbol, other)
Σημείωσε ότι ο κατασκευαστής String() λειτουργεί σε ένα Vector.
Για να μετατρέψεις έναν μόνο Char σε συμβολοσειρά ενός χαρακτήρα, η συνάρτηση είναι η string(), με πεζό s.
julia> string('a')
"a"
Όλα όσα είδαμε μέχρι τώρα στο κείμενο φαίνονται σχετικά απλά, οπότε δεν υπάρχει και πολύς λόγος να ανησυχείς;
Δυστυχώς, αυτό είναι υπερβολικά αισιόδοξο!
Μια επιπλοκή προκύπτει από την ανάγκη για "έως" 6 δεκαεξαδικά ψηφία ανά σημείο κώδικα. Αυτό σημαίνει ότι διαφορετικοί χαρακτήρες χρειάζονται διαφορετική ποσότητα χώρου στη μνήμη όταν κωδικοποιούνται σε UTF-8.
Ένα byte μπορεί να αποθηκεύσει μόνο (χωρίς πρόσημο) αριθμούς έως το 255, δύο δεκαεξαδικά ψηφία, οπότε το UTF-8 χρησιμοποιεί μεταβλητό αριθμό bytes (1 έως 4) για να αποθηκεύσει έναν Char.
Αυτά ονομάζονται "μονάδες κώδικα" και η συνάρτηση ncodeunits() θα επιστρέψει τον αριθμό που χρειάζεται για έναν δεδομένο χαρακτήρα.
julia> codepoint(jha) # jha 'झ' is defined in an earlier example
0x0000091d
julia> ncodeunits(jha)
3
julia> ncodeunits('a') # ASCII character
1
julia> ncodeunits('😱') # emoji
4
Επίσης, δεν έχει το καθετί που μπορεί να εμφανιστεί στην οθόνη το δικό του μοναδικό σημείο κώδικα. Κάποιοι οπτικά διακριτοί χαρακτήρες θεωρούνται ότι προέρχονται από άλλους, οπότε το Unicode τους αντιμετωπίζει ως έναν γονικό χαρακτήρα συν έναν τροποποιητή.
Αυτό το ζήτημα επηρεάζει τις συμβολοσειρές, όπου δημιουργεί προκλήσεις στην εύρεση θέσης.
Σε αυτή την άσκηση θα υλοποιήσεις ένα μερικό σύνολο βοηθητικών ρουτινών που βοηθούν έναν προγραμματιστή να καθαρίσει ονόματα αναγνωριστικών.
Στις 6 εργασίες θα χτίσεις σταδιακά τις συναρτήσεις transform, που μετατρέπει μεμονωμένους χαρακτήρες, και clean, που μετατρέπει συμβολοσειρές.
Ένα έγκυρο αναγνωριστικό αποτελείται από μηδέν ή περισσότερα γράμματα, κάτω παύλες, ενωτικά, ερωτηματικά και emoji.
Αν περάσεις μια κενή συμβολοσειρά στη συνάρτηση clean, θα πρέπει να επιστραφεί μια κενή συμβολοσειρά.
Υλοποίησε τη συνάρτηση transform ώστε να αντικαθιστά κάθε ενωτικό με κάτω παύλα.
julia> transform('-')
"_"
Αφαίρεσε όλους τους κενούς χαρακτήρες. Αυτό περιλαμβάνει τα κενά στην αρχή και στο τέλος.
julia> transform(' ')
""
Τροποποίησε τη συνάρτηση transform ώστε να μετατρέπει το camelCase σε kebab-case
julia> transform('D')
"-d"
Τροποποίησε τη συνάρτηση transform ώστε να παραλείπει όσους χαρακτήρες είναι αριθμητικοί.
julia> transform('7')
""
Τροποποίησε τη συνάρτηση transform ώστε να αντικαθιστά κάθε ελληνικό γράμμα στο εύρος από το 'α' έως το 'ω'.
julia> transform('β')
"?"
Υλοποίησε τη συνάρτηση clean ώστε να εφαρμόζει αυτές τις λειτουργίες σε μια ολόκληρη συμβολοσειρά.
Οι χαρακτήρες που δεν εμπίπτουν στους κανόνες θα πρέπει να περνούν αναλλοίωτοι.
julia> clean(" a2b Cd-ω😀 ")
"ab-cd_?😀"
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Julia με 35 έννοιες128 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.