*Komplexe Datentypen: Strings
*&str
*utf-8
Erklärung und Erzeugung von Strings
Es geht weiter mit den komplexen Datentypen. Diesmal nehmen wir uns die Strings vor. Wer noch nichts mit Programmieren am Hut hatte, dem kann ich sie mal, zumindest pauschaliert, als Text vorstellen. Aber es wäre kein Programmieren, würden wir nicht irgendwas damit aus dem Hut zaubern.
Anders als bei den bereits bekannten Datentypen, wird der String etwas anders aufgerufen. Es wird unterschieden, ob wir ihm sofort einen Wert geben wollen, oder später der Benutzer etwas eingibt. Hier auch schon der Hinweis, dass String DER Datentyp ist, welche der Eingabe eines Benutzers entsprechen. Dazu kommen wir aber bald.
let text1 = String::from("Hallo, du Stringtext.");
Erzeugt eine Variable, mit einem &str "Hallo, du Stringtext" , welche in einen dynamischen String konvertiert wird. Der Inhalt wird in der Variable text1 gespeichert. Im Prinzip ist damit schon der wesentliche Unterschied, zwischen String und &str geklärt. String Literale (&str) sind einfach nur unveränderliche Textbausteine und Strings sind hingegen wandelbar.
Deklaration von String-Literalen (&str)
Quasi in einem Zwischenstopp sollten wir uns dieses Thema ansehen. Der Aufbau ist im Prinzip einfach wie der eines primitiven Datentyps:
let text2 = "Hallo, ich bin ein String-Literal";
Zumindest ein paar Anmerkungen dazu: Man würde evtl. dazu neigen, den Text noch in in runde Klammern zu stecken. Das wäre aber falsch, denn das String-Literal ist gleichzeitig der Inhalt eines Strings und hätte ansonsten die komische Formationen (("....xxx...")). Gleichzeitig ist dieses &str ein String-Slice. Es wird also immer auch als Teil eines Strings gewertet.
.....
Aber weiter im Text.
Vorbereitung der Benutzereingabe
Um die Eingabe eines Benutzers in einen String zu speichern (das wie genau, kommt natürlich noch), verwendet man
let text2 = String::new();
Es ist also nur ein kleiner Vorgeschmack.
Verwendung von Strings
Im Prinzip ist es sinnvoll einen String als mut zu deklarieren, denn im Regelfall wollen wir ihn ändern. Anderweitig kann man ein String-literal einsetzen, das diesen Zweck erfüllen würde.
Will man zB nur irgendwo einen Buchstaben einfügen, wird
.push
verwendet.
text1.push('a');
fügt unserem String einen Char hinzu. Nachdem das vielleicht etwas langweilig ist, kann man ein gesamtes String-Literal einfach mit
.push_str.
dranhängen. Also,
text1.push_str("ein weiterer Anhang für den String");
Auf dem selben Weg kann man nun auch via .push_str ein &str, welches vorher in einer Variable gespeichert war verwenden.
let str_literal = "Hallo, ich bin aus einem bereits gespeicherten Text, der von einer Variable kommt";
Dieses &str fügt man mit dem Variablennamen wieder ein.
text1.push_str(str_literal);
schon ist das &str im String enthalten und könnte theoretisch auf diesem Weg immer wieder hinzugefügt werden.
Erklärung für UTF-8
Strings sind im Regelfall in UTF-8 gespeichert. Das liest man zwar öfters mal, aber was bedeutet das? Für meinen Fall, bin ich davon ausgegangen, dass es einfach eine Umformulierung des bekannten ASCII Codes ist (256 Zeichen, 8 bit). Aber nein, UTF-8 hat in etwa 150.000 Zeichen gespeichert. Das ist schon ein gewaltiger Unterschied, was? Was sind das plötzlich für neue Zeichen? Um das kurz zu fassen, sind es einfach alle Zeichen, die in allen bekannten Sprachen vorkommen und international anerkannt sind, sowie in selber Weise alle Symbole und Emoticons. (Da kommt ja einiges zusammen).
Warum sollte einem das interessieren?
Weil der UTF 8 in Zahlen/Ziffern codiert ist. Im Vorfeld ist es tatsächlich Standard-ASCII, von 0-255. Danach kann ein Zeichen bis zu 4 Bytes lang sein. Da könnte ein ASCII schon lange nicht mehr mithalten. Wie wird jetzt so eine Ausgabe formuliert?
let text3="Hallo!"; //erzeugen des &str
let x = text3.bytes(); // text3 wird in x gespeichert
println!("{x:?}"); // x wird ausgegeben.
Ausgabe
Das ist strenggenommen noch ASCII Code. Jedes Zeichen wird durch eine Zahl gespiegelt. Um das Zahlengeschwurbel etwas zu entwirren. Im ASCII Code ist das Große A auf 65, und das Kleine auf 97(das a von Hallo). Aus diesem Grund ist auch die 2te Zahl die 97. Aber verwenden wir doch mal ein Emoticon. Ein Smiley.
let text4="🙂";
let y = text4.bytes();
println!("{y:?}");
Ausgabe
Das eine Zeichen ist tatsächlich 4 Bytes lang. So, das wars mal fürs erste zu den Strings. Ich hoffe, ich habe es nicht zu kompliziert erklärt. Am Ende gibts wieder eine Code-Zusammenfassung mit Ausgabe, zum Kopieren.
fn main(){
let mut text1 = String::from("Hallo, du Stringtext.");
println!("text1 = {text1}");
let text2 = "Hallo, ich bin ein String-Literal"; //erzeugt ein Stringliteral
println!("text2, das Stringliteral &str ={text2}");
text1.push('a'); //fügt den Buchstaben 'a' zu text1
println!("text1 mit .push = {text1}");
text1.push_str("oder noch ein zusätzliches String-Literal."); //fügt via .push_str diesen Text hinzu
println!("{text1}");
let str_literal = " Oder man fügt nochmals ein Stringliteral in einer Variable hinzu"; // &str für text1
text1.push_str(str_literal); //hinzufügen von str_literal zu text1
println!("{text1}");
let text3="Hallo!"; //erzeugen des &str für die .bytes() Auflistung
let x = text3.bytes(); // text3 wird in x gespeichert
println!("{x:?}"); // x wird ausgegeben.
//let text2 = String::new(); > Das hier nur mal zum Zeigen. Vorbereitung der Benutzereingabe.
//let text4 = String::from("😀") ;
let text4="😀";
println!("{:?}",text4);
let y = text4.bytes();
println!("{y:?}");
}
}
Ausgabe