Rust String
String
The two types of strings found in Rust are String and &str.
String:
- A UTF-8 sequence is used to encode a string.
- Heap memory is used to allocate space for strings.
- A string can expand in length.
- The sequence is not null-terminated.
&str
Another name for “&str” is a string slice.
&[u8] is used to indicate the UTP-8 sequence.
To view the data included in the string, use ‘&str’.
Its size is set; that is, it cannot be altered.
Difference b/w 'String' and '&str'.
A String is an immutable reference to a string, but &str is an immutable reference; that is, we can modify the data of a String, but not the data of &str.
A String is the owner of its data; in contrast, &str borrows ownership from another variable.
Creating a new String
In the same way that we construct the vector, we build a String. Now let’s examine this:
String:
Let mut s = String::new();
The new() function is used to construct String s in the declaration above. Currently, we can use the to_string() method to initialize the String at the time of declaration.
- Applying the to_string() function to the given data:
let a = "javaTpoint";
let s = a.to_string();
- Alternatively, we may use the string literal directly to apply the to_string method:
let s = "javaTpoint".to_string();
Example:
fn main()
let data="javaTpoint";
let s=data.to_string();
print!("{} ",s);
let str="tutorial".to_string();
print!("{}",str);
Output:
javaTpoint tutorial
Using the String::from function, which is comparable to the String::new() function, is the second method of creating a String.
Example:
fn main()
{
let str = String::from("javaTpoint tutorial");
print!("{}",str);
}
Output:
javaTpoint tutorial
Updating a String
By inserting additional data into the String, we can modify both the String’s size and content. The format macro’s ‘+’ operator is likewise available to us! to combine the values in the string.
- Appending to a string with push_str and push
push_str() : The push_str() function allows us to increase the String’s size. The content is appended at the end of the string. Assume we have two strings, s1 and s2, and we wish to append s2 to s1.
s1.push_str(s2);
Example:
fn main()
{
let mut s=String::from("java is a");
s.push_str(" programming language");
print!("{}",s);
}
Output:
java is a programming language
The parameter is not assumed by the push_str() function. Let’s use a straightforward example to better grasp this situation.
fn main()
{
let mut s1 = String::from("Hello");
let s2 = "World";
s1.push_str(s2);
print!("{}",s2);
}
Output:
World
The last line of the program would not function and the value of the s2 would not be printed if the push_str() function assumed ownership of the parameter.
push(): To add a single character to the end of a string, use the push() method. Assume that the string is s1 and that the character ch has to be appended to the end of s1.
s1.push(ch);
Example:
fn main()
{
let mut s = String::from("java");
s.push('c');
print!("{}",s);
}
Output:
javac
Concatenation with the '+' operator or format macro
Operator “+”: Two strings can be joined together with the ‘+’ operator. Let’s examine:
let s1 = String::from("javaTpoint ");
let s2 = String::from("tutorial!!");
let s3 = s1+&s2;
Example:
fn main()
{
let s1 = String::from("javaTpoint");
let s2 = String::from(" tutorial!!");
let s3 = s1+&s2;
print!("{}",s3);
}
Output:
javaTpoint tutorial!!
The javaTpoint lesson is the result of concatenating two strings in the example above, and it is included in s3. The reference of the s2, or &s2, is used in place of the’s1′ since it is no longer valid, as per the method signature that is called when the ‘+’ operator is used. The add() method, whose declaration is provided below, is called by the ‘+’ operator:
fn add(self,s:&str)->String
{
}
First of all, the fact that s2 has the ‘&’ operator indicates that s1 is being referenced. The add() function’s signature indicates that while we can add &str to a String, we are unable to add two string values together. But based on the second parameter given in the add() method, the type of s2 is &String and not &str. However, because the compiler forces the &string to become &str, we may still utilize the s2 in the add method. Thus, we may conclude that Rust employs deref coercion when we invoke the add() method.
Second, self is the function’s initial parameter, and add() assumes ownership of self. This indicates that after the phrase let s3=s1+&s2;, s1 is no longer acceptable.
format! Macro
- Using the ‘+’ operator becomes particularly awkward when we want to concatenate numerous strings. The format macro should be used in order to concatenate the numerous strings.
- Like println! macro, format macro operates in a similar way. The content of the string is returned by format macro instead of printing on the screen, which is how it differs from println!
macro.
Example:
fn main()
{
let s1 = String::from("C");
let s2 = String::from("is");
let s3 = String::from("a");
let s4 = String::from("programming");
let s5 = String::from("language.");
let s = format!("{} {} {} {} {}",s1,s2,s3,s4,s5);
print!("{}",s);
}
Output:
C is a programming language.
Indexing into Strings
A UTF-8 sequence is used to encode a string. The string cannot be indexed as a result. Let’s use the following example to better grasp this idea:
fn main()
{
let s = String::from("javaTpoint");
print!("{}",s[1]);
}
Output:
error[E0277]: the trait bound `std::string::String: std::ops::Index<{integer}>` is not satisfied
--> jdoodle.rs:4:17
|
4 | print!("{}",s[1]);
| ^^^^ the type `std::string::String` cannot be indexed by `{integer}`
|
= help: the trait `std::ops::Index<{integer}>` is not implemented for `std::string::String`
error: aborting due to previous error
Using an index to get data is incredibly quick. However, the string is encoded as a UTF-8 sequence, which may contain several bytes, and it will cost money to locate the nth character in a string.
Slicing Strings
Since it is unknown whether the return type of the indexing operation should be a character, byte value, or a string slice, indexing is not supplied in the string. Rust gives you a more precise method of indexing the string by giving you a range inside [] instead of just one integer.
let s = "Hello World";
let a = &s[1..4];
The string literal, Hello World, is contained in s in the case above. When we specify [1..4] indices, it indicates that the substring from a string with an index between 1 and 3 is being retrieved.
fn main() {
let s = "Hello World";
let a = &s[1..4];
print!("{}",a);
}
Output:
ell
Methods for iterating over strings
The string is also accessible to us in other ways. We can loop through each string element by using the chars() method.
Example:
fn main()
{
let s = "C is a programming language";
for i in s.chars()
{
print!("{}",i);
}
}
Output:
C is a programming language