You can use char_indices() then slice the string according to the positions the iterator gives you:

let mut iter = s.char_indices();
let (start, _) = iter.nth(10).unwrap();
let (end, _) = iter.nth(5).unwrap();
let slice = &s[start..end];

However, note that as mentioned in the documentation of chars():

It’s important to remember that char represents a Unicode Scalar Value, and might not match your idea of what a ‘character’ is. Iteration over grapheme clusters may be what you actually want. This functionality is not provided by Rust’s standard library, check crates.io instead.

Answer from Chayim Friedman on Stack Overflow
🌐
Rust Programming Language
users.rust-lang.org › help
How to get a substring of a String - help - The Rust Programming Language Forum
May 14, 2015 - Hi, what is the best way to get a substring of a String? I couldn't find a substr method or similar. Let's assume I have a String like "Golden Eagle" and I want to get the first 6 characters, that is "Golden". How ca…
🌐
Dot Net Perls
dotnetperls.com › substring-rust
Rust - Substring Examples - Dot Net Perls
Note 2 If we omit the last, the slice continues until no more characters are available. Here This Rust program takes the first 2 characters. To take the last 2, it uses len() to count back 2 from the total string length. fn main() { let value = "abcdef"; // Get first 2 characters. let result1 = &value[..2]; println!("SUBSTRING: {}", result1); // Get last 2 characters.
🌐
The Rust Programming Language
doc.rust-lang.org › book › ch04-03-slices.html
The Slice Type - The Rust Programming Language
Rather than a reference to the entire String, hello is a reference to a portion of the String, specified in the extra [0..5] bit. We create slices using a range within square brackets by specifying [starting_index..ending_index], where starting_index is the first position in the slice and ending_index is one more than the last position in the slice.
🌐
Rust
doc.rust-lang.org › std › primitive.str.html
str - Rust
Returns a string slice with the prefix and suffix removed. If the string starts with the pattern prefix and ends with the pattern suffix, returns the substring after the prefix and before the suffix, wrapped in Some.
🌐
Rust
docs.rs › substring
substring - Rust
use substring::Substring; // Works on a string slice. assert_eq!("foobar".substring(2,5), "oba"); // Also works on a String. assert_eq!("foobar".to_string().substring(1,6), "oobar"); As Rust strings are UTF-8 encoded, the algorithm for finding a character substring is O(n), where n is the byte length of the string...
Top answer
1 of 2
4

You can use char_indices() then slice the string according to the positions the iterator gives you:

let mut iter = s.char_indices();
let (start, _) = iter.nth(10).unwrap();
let (end, _) = iter.nth(5).unwrap();
let slice = &s[start..end];

However, note that as mentioned in the documentation of chars():

It’s important to remember that char represents a Unicode Scalar Value, and might not match your idea of what a ‘character’ is. Iteration over grapheme clusters may be what you actually want. This functionality is not provided by Rust’s standard library, check crates.io instead.

2 of 2
2

@ChayimFriedman's answer is of course correct, I just wanted to contribute a more telling example:

fn print_string(s: &str) {
    println!("String: {}", s);
}

fn main() {
    let s: String = "".to_string();

    let mut iter = s.char_indices();

    // Retrieve the position of the char at pos 1
    let (start, _) = iter.nth(1).unwrap();

    // Now the next char will be at position `2`. Which would be
    // equivalent of querying `.next()` or `.nth(0)`.
    // So if we query for `nth(2)` we query 3 characters; meaning
    // the position of character 4.
    let (end, _) = iter.nth(2).unwrap();

    // Gives you a &str, which is exactly what you want.
    // A reference to a substring, zero allocations, zero overhead.
    let substring = &s[start..end];

    print_string(&s);
    print_string(substring);
}
String: 
String: 

I've done it with smileys because smileys are definitely multi-byte unicode characters.

As @ChayimFriedman already noted, the reason why we have to iterate through the char_indices is because unicode characters are variably sized. They can be anywhere from 1 to 8 bytes long, so the only way to find out where the character boundaries are is to actually read the string up to the character we desire.

🌐
DEV Community
dev.to › alexmercedcoder › in-depth-guide-to-working-with-strings-in-rust-1522
In-Depth Guide to Working with Strings in Rust - DEV Community
September 14, 2024 - While basic string operations are ... search for substrings or patterns within strings using methods like contains(), find(), and starts_with()/ends_with()....
Find elsewhere
🌐
Rust Programming Language
users.rust-lang.org › t › rust-substring-function › 24854
Rust substring function? - The Rust Programming Language Forum
February 1, 2019 - I am aware of String in std::string - Rust I can not find a function 'substring' where it takes two args, start (inclusive) nd end (exclusive), and returns a &str pointing to the cahrs in between. Does this strin…
🌐
Rust
doc.rust-lang.org › std › string › struct.String.html
String in std::string - Rust
Returns a string slice with the prefix removed. If the string starts with the pattern prefix, returns the substring after the prefix, wrapped in Some.
Top answer
1 of 2
2

Your code example is not very complete. The part that actually causes the error can't be seen in your example.

I guess that your code looks something like this:

pub fn function1(s: String) -> i32 {
    let index: &i32 = &1;
    let substring = (&s[index..]).to_string();
    let counter = function1(substring);
    10
}
error[E0277]: the type `String` cannot be indexed by `RangeFrom<&i32>`
 --> src/main.rs:3:23
  |
3 |     let substring = (&s[index..]).to_string();
  |                       ^^^^^^^^^^ `String` cannot be indexed by `RangeFrom<&i32>`
  |
  = help: the trait `Index<RangeFrom<&i32>>` is not implemented for `String`

Problems

  • index must be a usize, but it is an &i32. This is the main error that you see.
  • You cannot slice a string directly, you need to convert from char-based indices to byte-based indices first. This can be done by iterating through char_indices().

Here is a rough sketch of how this might look like:

pub fn function1(s: String) -> i32 {
    println!("s: {}", s);

    let index: &i32 = &1;

    // Try to convert the index to a byte position
    let substring = match s.char_indices().nth(*index as usize) {
        // If a position with the given index was found in the string, create a substring
        Some((pos, _)) => (&s[pos..]).to_string(),
        // Else, create an empty string
        None => "".to_string(),
    };

    // Break if the substring is empty, otherwise we would have an infinite recursion
    if substring.is_empty() {
        return 0;
    }

    let counter = function1(substring);
    counter + 1
}

fn main() {
    let input_str = "".to_string();
    let result = function1(input_str);
    println!("Result: {}", result);
}
s: 
s: 
s: 
s: 
Result: 3

Slicing vs copying

With every iteration of your function, you are creating a new copy of the string. This is quite slow, and I don't see a reason why this would be necessary in your case.

What you really want is a slice of the input string. This doesn't copy any data, it simply references a part of the original string.

To achieve that, you would have to change your parameter type from String to &str. There is no reason your function would need to take ownership. Even if you want to take ownership, then to_string() would do so, as it creates a copy of the data. So there really is no reason to use String as the parameter type.

pub fn function1(s: &str) -> i32 {
    println!("s: {}", s);

    let index: &i32 = &1;

    // Try to convert the index to a byte position
    let substring = match s.char_indices().nth(*index as usize) {
        // If a position with the given index was found in the string, create a substring slice
        Some((pos, _)) => &s[pos..],
        // Else, use an empty string
        None => "",
    };

    // Break if the substring is empty, otherwise we would have an infinite recursion
    if substring.is_empty() {
        return 0;
    }

    let counter = function1(substring);
    counter + 1
}

fn main() {
    let input_str = "".to_string();
    let result = function1(&input_str);
    println!("Result: {}", result);
}
s: 
s: 
s: 
s: 
Result: 3
2 of 2
1

You couldn't indexing a string in rust, because strings are encoded in UTF-8. You could use the method chars and/or char_indices

As from your given code, I can't figure out what method you should use. Have a look at the rust doc.

For further information:

https://doc.rust-lang.org/std/string/struct.String.html

https://doc.rust-lang.org/std/string/struct.String.html#method.chars

https://doc.rust-lang.org/std/string/struct.String.html#method.char_indices

https://doc.rust-lang.org/std/string/struct.String.html#method.split_whitespace

🌐
MIT
web.mit.edu › rust-lang_v1.25 › arch › amd64_ubuntu1404 › share › doc › rust › html › std › primitive.str.html
str - Rust
Implements mutable substring slicing with syntax &mut self[.. end]. Returns a mutable slice of the string from the beginning to byte offset end.
🌐
Rust
docs.rs › stringslice
stringslice - Rust
use stringslice::StringSlice; assert_eq!("Γεια σου κόσμε".substring(9, 14), "κόσμε"); There are also equivalent try_slice and try_substring methods which return None for invalid input.
🌐
Rust
docs.rs › arcstr › latest › arcstr › struct.Substr.html
Substr in arcstr - Rust
The pattern can be a &str, char, a slice of chars, or a function or closure that determines if a character matches. Equivalent to split, except that the trailing substring is skipped if empty. This method can be used for string data that is terminated, rather than separated by a pattern.
🌐
crates.io
crates.io › crates › substring
substring - crates.io: Rust Package Registry
For full functionality of this site it is necessary to enable JavaScript
🌐
Wduquette
wduquette.github.io › parsing-strings-into-slices
Parsing Rust Strings into Slices
The Chars iterator can return a &str slice containing the remainder of the source string. It’s easy to compute a slice from two slices one of which completely contains the other. For the record, I found the solution at users.rust-lang.org.
🌐
Rust Internals
internals.rust-lang.org › language design
Substring slice pattern matching - language design - Rust Internals
June 13, 2022 - I could not find the following proposal discussed anywhere, which is surprising, since it looks like a very natural addition. The proposal is to add substring pattern syntax for pattern-matching, which would serve the same purpose as the slice patterns for slices and arrays.
🌐
Rust-guide
rust-guide.com › en › documentation › collections › str
The Rust Guide - str
Splits the string slice by a specified delimiter and returns an iterator over the substrings.
🌐
MIT
web.mit.edu › rust-lang_v1.25 › arch › amd64_ubuntu1404 › share › doc › rust › html › book › second-edition › ch04-03-slices.html
Slices - The Rust Programming Language
Figure 4-6: String slice referring to part of a String · With Rust’s .. range syntax, if you want to start at the first index (zero), you can drop the value before the two periods.
🌐
Eze Sunday
ezesunday.com › home › rust string manipulations
Rust string manipulations - Eze Sunday
August 23, 2025 - The + operator (provided by the Add trait) isn’t implemented for string slices, so you can’t directly concatenate them. However, you can achieve the same result with this approach: let new_string = String::from("Hello") + ", world!"; As a quick aside, in Rust, the :: syntax is called the “path separator” and is used to access items within a module, struct, or enum.