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
Answer from Finomnis on Stack Overflow
🌐
The Rust Programming Language
doc.rust-lang.org › book › ch04-03-slices.html
The Slice Type - The Rust Programming Language
Internally, the slice data structure stores the starting position and the length of the slice, which corresponds to ending_index minus starting_index. So, in the case of let world = &s[6..11];, world would be a slice that contains a pointer to the byte at index 6 of s with a length value of 5. ...
🌐
TutorialsPoint
tutorialspoint.com › rust › rust_slices.htm
Rust - Slices
fn main() { let n1 = "Tutorials".to_string(); println!("length of string is {}",n1.len()); let c1 = &n1[4..9]; // fetches characters at 4,5,6,7, and 8 indexes println!("{}",c1); } ... The main() function declares an array with 5 elements. It invokes the use_slice() function and passes to it ...
🌐
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.
🌐
Rust
doc.rust-lang.org › std › primitive.slice.html
slice - Rust
Returns an iterator that produces an escaped version of this slice, treating it as an ASCII string.
🌐
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 - One of the primary performance considerations with strings in Rust is avoiding unnecessary heap allocations. Since String is a heap-allocated data structure, repeatedly creating and modifying String objects can result in unnecessary memory allocations and deallocations, which may slow down your program. Prefer &str Over String When Possible: If you don’t need to modify or own the string data, prefer using string slices (&str) instead of String.
🌐
Programiz
programiz.com › rust › slice
Rust Slice (With Examples)
Just like an array, we can also slice a string in Rust. For example,
🌐
Rust
doc.rust-lang.org › std › primitive.str.html
str - Rust
If you are sure that the byte slice is valid UTF-8, and you don’t want to incur the overhead of the validity check, there is an unsafe version of this function, from_utf8_unchecked, which has the same behavior but skips the check. If you need a String instead of a &str, consider String::from_utf8. Because you can stack-allocate a [u8; N], and you can take a &[u8] of it, this function is one way to have a stack-allocated string. There is an example ...
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

Find elsewhere
🌐
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.
🌐
DEV Community
dev.to › francescoxx › slices-in-rust-g6
Slices in Rust - DEV Community
March 5, 2024 - As a final note, the type of s2 is &str, which is a slice of a string. This means that s2 is a reference to a contiguous sequence of characters in memory. So we can remove the &s2 from the first_word function and the code will still work. In this lesson, we explored the Slice type in Rust.
🌐
Rust
docs.rs › slicestring
slicestring - Rust
It also works with emoticons since the slice() method takes into account characters. let mut s = String::from("hello 😃"); s = s.slice(5..); assert_eq!("😃", s);
🌐
Medium
medium.com › @python-javascript-php-html-css › understanding-string-slices-in-rust-why-str-needs-an-ampersand-7b99deff3b71
Understanding String Slices in Rust: Why &str Needs an Ampersand
November 18, 2024 - For instance, in the example `let z: &str = &x[2..4];`, the ampersand ensures that the slice `z` cannot outlive the original slice `x`. Without this, the compiler would throw an error, highlighting a potential violation of memory safety.
🌐
Rust
doc.rust-lang.org › std › string › struct.String.html
String in std::string - Rust
In certain cases Rust doesn’t have enough information to make this conversion, known as Deref coercion. In the following example a string slice &'a str implements the trait TraitExample, and the function example_func takes anything that implements the trait.
🌐
Exercism
exercism.org › tracks › rust › concepts › string-slices
String Slices in Rust on Exercism
There are two ways that Rust implements an array of characters: str and String. str, also known as a "string slice", is usually used with a reference as &str.
🌐
Rust
doc.rust-lang.org › std › str › index.html
std::str - Rust
An iterator over the non-whitespace substrings of a string, separated by any amount of whitespace. ... An item returned by the Utf8Chunks iterator. ... An iterator used to decode a slice of mostly UTF-8 bytes to string slices (&str) and byte slices (&[u8]).
🌐
Rust Exercises
rust-exercises.com › 100-exercises › 04_traits › 06_str_slice.html
String slices - 100 Exercises To Learn Rust
A &str is a view into a string, a reference to a sequence of UTF-8 bytes stored elsewhere. You can, for example, create a &str from a String like this: let mut s = String::with_capacity(5); s.push_str("Hello"); // Create a string slice reference from the `String`, // skipping the first byte.
🌐
NAPALM
saidvandeklundert.net › learn › 2021-08-14-rust-slice
Rust slice
The string slice is a &str, so we would not be able to pass it into the return_second function. In fact, the string slice is a bit ‘special’. All strings in Rust are UTF-8 and therefore, characters can differ in size. The iter() does not work on string slices, instead, we need to turn to chars().
🌐
Rust Programming Language
users.rust-lang.org › t › basic-topic-string-and-string-slice › 41479
Basic-Topic-String-and-string-Slice - The Rust Programming Language Forum
April 24, 2020 - For example I need to use like let str1 : &str = "Chennai" ; Why not like let str1: str = "Chennai" When I use without reference, the rust compiler says that error[E0308]: mismatched types --> string1.rs:4:22 | 4 | let str1: str = "Chennai"; ...