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
Figure 4-7: A string slice referring to part of a String Β· With Rust’s .. range syntax, if you want to start at index 0, you can drop the value before the two periods.
🌐
Rust
doc.rust-lang.org β€Ί std β€Ί string β€Ί struct.String.html
String in std::string - Rust
It should accept byte indices (to be constant-time) and return a &str which is UTF-8 encoded. This is also called β€œstring slicing”. Note this will panic if the byte indices provided are not character boundaries - see is_char_boundary for more details. See the implementations for SliceIndex<str> ...
Discussions

Newbie Question: String Slices
Everything can be represented as a &str so with a reference to a slice as a parameter the function can be used with both strings, string literals and slices. A &str is just a fat pointer to you string so it costs nothing to have around. I like this blog post about slicing vs string vs referencing: https://blog.thoughtram.io/string-vs-str-in-rust/ . It explains the subject perfectly. It may help you a bit with this. It helped me. More on reddit.com
🌐 r/rust
10
5
December 13, 2020
rust - String from slice - Stack Overflow
my function takes String, I understand that this is not very cool, but &String can not use, I want without losing ownership of the original string to pass it into the same function but take a More on stackoverflow.com
🌐 stackoverflow.com
rust str slice from string - Stack Overflow
"A slice is a kind of reference, so it does not have ownership." The following code is simplified. It needs to return a slice using a match. All but one match arm return a string slice. ... More on stackoverflow.com
🌐 stackoverflow.com
Confused by the purpose of str and String
I recently wrote a string guide: http://doc.rust-lang.org/guide-strings.html Specific criticisms/improvements very welcome. More on reddit.com
🌐 r/rust
51
24
July 25, 2014
🌐
Rust
doc.rust-lang.org β€Ί std β€Ί primitive.str.html
str - Rust
A string slice (&str) is made of bytes (u8), and a byte slice (&[u8]) is made of bytes, so this function converts between the two. Not all byte slices are valid string slices, however: &str requires that it is valid UTF-8.
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

🌐
Rustplatform
rustplatform.com β€Ί strings-and-slices
Strings and Slices - Pybites Rust Platform
Rust strings work differently because of its ownership model. There are two main string types: &str β€” a string slice. A borrowed, read-only view into string data.
Find elsewhere
🌐
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.
🌐
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
docs.rs β€Ί slicestring
slicestring - Rust
It slices the String or &str and returns a the sliced one as a 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.
🌐
MIT
web.mit.edu β€Ί rust-lang_v1.25 β€Ί arch β€Ί amd64_ubuntu1404 β€Ί share β€Ί doc β€Ί rust β€Ί html β€Ί book β€Ί first-edition β€Ί strings.html
Strings - The Rust Programming Language
Rust has two main types of strings: &str and String. Let’s talk about &str first. These are called β€˜string slices’. A string slice has a fixed size, and cannot be mutated.
🌐
DEV Community
dev.to β€Ί dsysd_dev β€Ί string-vs-str-in-rust-understanding-the-fundamental-differences-for-efficient-programming-4og8
String vs str in Rust: Understanding the Fundamental Differences for Efficient Programming - DEV Community
July 31, 2023 - The use of string slices allows Rust to efficiently work with and manipulate parts of strings without incurring unnecessary memory copies, making it a memory-safe and high-performance language for string handling.
🌐
Stack Overflow
stackoverflow.com β€Ί questions β€Ί 70777076 β€Ί rust-str-slice-from-string
rust str slice from string - Stack Overflow
"A slice is a kind of reference, so it does not have ownership." The following code is simplified. It needs to return a slice using a match. All but one match arm return a string slice. ...
🌐
Rust
doc.rust-lang.org β€Ί std β€Ί str
std::str - Rust
An iterator over the lines of a string, as string slices.
🌐
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 - In the provided example, slicing the string β€œhello” into smaller parts using index ranges highlighted an important distinction between `str` and `&str`. A string slice, such as `&str`, is essentially a borrowed reference to a part of the string.
🌐
MIT
web.mit.edu β€Ί rust-lang_v1.25 β€Ί arch β€Ί amd64_ubuntu1404 β€Ί share β€Ί doc β€Ί rust β€Ί html β€Ί std β€Ί primitive.str.html
Primitive Type str - Rust
This new slice goes from begin to end, including begin but excluding end. To get an immutable string slice instead, see the slice_unchecked method.
🌐
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.
🌐
Programiz
programiz.com β€Ί rust β€Ί slice
Rust Slice (With Examples)
fn main() { let string = String::from("Hello World!"); // slicing a string let slice = &string[0..5]; println!("string = {}", string); println!("slice = {}", slice); } ... To learn more about strings in Rust, visit Rust String.