Υπάρχουν δύο τρόποι με τους οποίους η Rust υλοποιεί έναν πίνακα χαρακτήρων: str και String.
Το str, γνωστό και ως "τμήμα συμβολοσειράς", χρησιμοποιείται συνήθως με μια αναφορά, ως &str.
Για να καταλάβεις τον λόγο, ίσως βοηθήσει να δεις γιατί η παρακάτω γραμμή κώδικα δεν μεταγλωττίζεται
const MY_CONST: str = *"Hello, World!";
// the size for values of type `str` cannot be known at compilation time
// the trait `Sized` is not implemented for `str`
Ακόμα κι αν το μήκος του literal "Hello, World!" μπορεί να είναι γνωστό σε χρόνο μεταγλώττισης, ως str είναι μια ακολουθία άγνωστου μεγέθους.
Αλλά ως αναφορά σε ένα literal (&str), έχει έναν "παχύ δείκτη" ο οποίος κρατά τη διεύθυνση και το μήκος του literal στη μνήμη.
Οι παχείς δείκτες έχουν γνωστό μέγεθος, και έτσι αυτή η γραμμή θα μεταγλωττιστεί
const MY_CONST: &str = "Hello, World!";
Μια mutable δέσμευση σε ένα τμήμα συμβολοσειράς μπορεί να αντικαταστήσει την τιμή της, αλλά όχι να την τροποποιήσει επιτόπου.
Παράδειγμα
let mut my_str = "Hello, World!";
my_str = "Hi!";
let mut my_string = String::from("Hello");
my_string.push_str(", World!"); // there is no equivalent function to modify &str
Είναι λιγότερο περιοριστικό να χρησιμοποιείς &str αντί για &String όταν ορίζεις μια παράμετρο για μια συνάρτηση, αφού το παρακάτω δεν μεταγλωττίζεται
pub fn main() {
let my_str: &str = "Hello, World!";
say_hi(my_str);
}
fn say_hi(phrase: &String) {
println!("{phrase:?}");
}
// mismatched types
// expected reference `&String`
// found reference `&str`
Ένα &str δεν θα εξαναγκαστεί σε &String. Αυτό όμως θα μεταγλωττιστεί
pub fn main() {
let my_string = String::from("Hello, World!");
say_hi(&my_string)
}
fn say_hi(phrase: &str) {
println!("{phrase:?}");
}
Ένα &String θα εξαναγκαστεί σε &str. Έτσι, το να χρησιμοποιείς τύπο παραμέτρου &str θα είναι συχνά πιο χρήσιμο.