String to str slice, str slice does not live long enough [duplicate] - string

This question already has answers here:
How to convert a String into a &'static str
(4 answers)
Closed 7 years ago.
OK, here's my MCVE, right off the bat.
fn do_something (string: &'static str) -> Result<&str, isize> {
Ok(string)
}
fn main() {
let place = Some("hello".to_string());
match place {
Some(input) => {
let place = &input[..];
let something = do_something(place);
}
_ => (),
}
}
I can't seem to figure out a way in which to satisfy do_something. In my actual code, do_something is a library function, so I can't change it's signature.
- Thanks

If you can't change the function's signature, then you either need to use a string literal to create a &'static str or leak memory.
i.e. either do this:
do_something("hello");
or this (bad idea, will probably break, only works on nightly):
let place = Some("hello".to_string());
if let Some(s) = place {
do_something(unsafe { std::mem::transmute(s.into_boxed_str()) });
}

Related

How can I handle this error in closure right in rust [duplicate]

This question already has answers here:
How do I bubble up an error from the closure passed to regex::Regex::replace?
(2 answers)
Closed 2 years ago.
I have a rust function which uses regex to replace string matching a certain rule. I am using the rust regex library, but I can't figure out how to handle error when using the closure.
My app has a custom error handler and I want to map the error returned in this function
pub fn override_from_env(content: &mut String) -> Result<()> {
*content = regex!(r"\B\$\{([A-Z0-9_]*?)\}")
.replace_all(&content, |captures: &Captures| {
let key = captures.get(1).unwrap().as_str();
match ::std::env::var(key) {
Ok(val) => val,
Err(e) => {
Error::EnvVarError(e);
String::from("") // this is not necessary, I want to return the error outside the closure here
}
}
})
.into_owned();
Ok(())
}
I was able to refactor this using capture_iter
pub fn transform_from_env(template: &mut String) -> Result<String> {
let mut content = String::new();
let mut last = 0;
let re = regex!(r"\B\$\{([A-Z0-9_]*?)\}");
for cap in re.captures_iter(&template) {
let range = cap.get(0).unwrap();
content.push_str(&template[last..range.start()]);
let key = cap.get(1).unwrap().as_str();
::std::env::var(key).map(|val| {
content.push_str(&val);
})?;
last = range.end();
}
if content.len() == 0 && template.len() > 0 {
content = template.to_string();
}
Ok(content)
}

rust, work around: cannot return value referencing local variable [duplicate]

This question already has answers here:
Return local String as a slice (&str)
(7 answers)
Closed 7 years ago.
Simple code:
fn foo() -> Vec<&'static str> {
let mut vec = Vec::new();
let mut string = String::new();
// doing something with string...
vec.push(string.as_str());
return vector; // error here: string doesn't live long enough
}
I have problem that I need to process with string and return it in Vec as str. Problem is that binding string doesn't live long enough, since it goes out of scope after foo. I am confused and I don't really know how to solve that.
A &'static str is a string literal e.g. let a : &'static str = "hello world". It exists throughout the lifetime of the application.
If you're creating a new String, then that string is not static!
Simply return a vector of String.
fn foo() -> Vec<String> {
let mut vec = Vec::new();
let mut string = String::new();
// doing something with string...
vec.push(string);
return vec;
}
fn main() {
foo();
}

What does [..] mean for Rust slices and what is it called? [duplicate]

This question already has answers here:
What does the "two periods" operator mean in the context of a subscript inside of square brackets?
(2 answers)
Closed 3 years ago.
I've found this example in a README:
use std::env;
fn main() {
let filename: &str = &env::args().nth(1).unwrap()[..];
let filename2: &str = &env::args().nth(1).unwrap();
println!("{:?}", filename);
println!("{:?}", filename2)
}
I'm interested in the first line: let filename ....
What does the [..] after the unwrap mean?
The second line let filename2 ... is my own test that both filename and filename2 are the same, or do I miss something?
What is this [..] called?
A string can be used as an array of bytes. This addition does strictly nothing:
#![feature(core_intrinsics)]
fn print_type_of<T>(_: &T) {
println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}
fn main() {
let x = "abc";
print_type_of(&x); // &str
let x = &x[..];
print_type_of(&x); // &str
}
[..] takes the full range, and & takes a reference to it.

Quick function to convert a String's first letter to uppercase? [duplicate]

This question already has answers here:
Why is capitalizing the first letter of a string so convoluted in Rust?
(9 answers)
Closed 4 years ago.
Does anyone know a function that changes the first letter of a String to the uppercase equivalent?
Idealy, it would be used as so:
let newfoo = first_letter_to_uppper_case("foobar".to_string()), or
let newfoo = "foobar".to_string().first_letter_to_uppper_case().
If you want a function used as so:
let newfoo = first_letter_to_uppper_case("foobar".to_string())
Try use the following:
fn main() {
println!("{}", first_letter_to_uppper_case("foobar".to_string()));
}
fn first_letter_to_uppper_case (s1: String) -> String {
let mut c = s1.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
}
If you want it as a function implimented on the string type, like let newfoo = "foobar".to_string().first_letter_to_uppper_case(), try:
pub trait FirstLetterToUppperCase {
fn first_letter_to_uppper_case(self) -> String;
}
impl FirstLetterToUppperCase for String {
fn first_letter_to_uppper_case(self) -> String {
let mut c = self.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
}
}
fn main() {
println!("{}", "foobar".to_string().first_letter_to_uppper_case());
}
However, these functions do not deal with non-ascii characters very well. For more information, see this answer.

Return local String as an Option<&str> [duplicate]

This question already has answers here:
Return local String as a slice (&str)
(7 answers)
Closed 7 years ago.
I want to write a function that receives a &str argument and returns Option<&str>. I wrote this:
fn f(text: &str) -> Option<&str> {
if // some condition {
return None;
}
let mut res = String::new();
// write something into res.
// return res
Some(&res[..])
}
but I get an error:
res does not live long enough.
What is the best solution to fix this?
You cannot return a &str that points into a local String variable. Doing that would mean that you just returned a dangling pointer, as the String (res, in your code) is destroyed when the function returns.
The best way to fix your problem is probably to return a Option<String>, i.e. return the owned string instead of a string slice. Adapting your code, you might end up with something like this:
fn f(text: &str) -> Option<String> {
if // some condition {
return None;
}
let mut res = String::new();
// write something into res.
Some(res)
}

Resources