This question already has answers here:
How do I create a global, mutable singleton?
(7 answers)
How to create a static string at compile time
(3 answers)
What are the differences between Rust's `String` and `str`?
(14 answers)
Closed 2 years ago.
There is a ALPHABET for arithmetic, it's const and used in a lot of functions. I want make the ALPHABET global, static, and const. Some functions need the ALPHABET type as &String, but str.to_string() function will happen once memory copy. this function is called frequently, so it's not good.
The used function is a library, can't change it.
static ALPHABET: &str = "xxxxxxxxxxxxxxxxxxxxxxx";
fn some1(value: &String, alphabet: &String) -> String {
xxxx
}
fn main() {
some1("test", ALPHABET); // Can't build
some1("test", &ALPHABET.to_string()); // OK, but will happend memory copy.
}
How use the ALPHABET without to_string() function?
It would be better if your function uses &str instead:
fn some1(value: &str, alphabet: &str) -> String {
xxxx
}
Playground
Since this is in a library you cannot modify, you could use lazy_static to instantiate a static reference to the String:
use lazy_static::lazy_static; // 1.4.0
lazy_static! {
static ref APLHABET: String = "xxxxxxxxxxxxxxxxxxxxxxx".to_string();
}
Playground
Related
This question already has answers here:
How to format a const string
(2 answers)
Is there a static alternative of format!()?
(3 answers)
Closed 9 months ago.
I have a simple template like "hello {blank} how are you?"
and 2 separate functions that need to hard code "blank" with static values (can be known at compile time).
I don't want to hard code this templated text to the functions.
I'm looking for something like a C #DEFINE macro which will just "stick" the value into the string.
Contrived:
// my macro/ const function or what ever needs to be here:
const fn / macro! fill_text(name: &str) -> {return format!("hello {name} how are you") } // at compile time should be evaluated, not at run time
fn say_hello_to_john() ->&'static str {
fill_text("john")
}
fn say_hello_to_jane() -> &'static str {
fill_text("jane")
}
Tried this but it doesn't yield a static string:
macro_rules! fill_text {
$text:expr => {
format!("hello {} how are you", $text) // how to make this static?
}
}
This question already has answers here:
How to fix lifetime error when function returns a serde Deserialize type?
(2 answers)
Return local String as a slice (&str)
(7 answers)
Closed 2 years ago.
I am trying to write a wrapper function for read a string that contains Vec[u8] (that are really just MsgPacks) and convert them to native rust structs, my code looks like this
use rmp_serde::{decode, from_slice};
use serde::Deserialize;
#[derive(Debug)]
pub enum MsgPackParseErr {
ParseIntError,
SerdeError,
}
impl From<std::num::ParseIntError> for MsgPackParseErr {
fn from(_e: std::num::ParseIntError) -> Self {
return Self::ParseIntError;
}
}
impl From<decode::Error> for MsgPackParseErr {
fn from(_e: decode::Error) -> Self {
return Self::SerdeError;
}
}
pub fn msgpack_from_byte_string<'b, T>(raw: String) -> Result<T, MsgPackParseErr>
where
T: Deserialize<'b>,
{
let parsing_string: Result<Vec<u8>, _> = raw.split(" ").map(|x| x.parse()).collect();
let parsed_string = parsing_string?;
let parsing_obj = from_slice(&parsed_string);
Ok(parsing_obj?)
}
But I am getting the error
temporary value dropped while borrowed
creates a temporary which is freed while still in use
For lines 23 to 28 i.e.
let parsing_obj = from_slice(&parsed_string);
Ok(parsing_obj?)
I have no idea what I am doing wrong here...
Your error comes from the fact that T: Deserialize<'b> in your code constrains T to live only as long as the lifetime 'b which in turn means it can't outlive whatever the input to from_slice was (otherwise it would be a use after free error).
pub fn msgpack_from_byte_string<'b, T>(raw: String) -> Result<T, MsgPackParseErr>
where
T: Deserialize<'b>
So why can't your serialized object be alive longer than the data associated with it? If possible, serde avoids the copy of the input data and allocation of extra fields by directly referencing the input buffer. This is also explained in more detail in the serde manual chapter about lifetimes.
Note that serde has also other traits that may be more appropriate for your use-case and are not constrained to the lifetime of the input (e.g., DeserializeOwned).
This question already has answers here:
How to make a compiled Regexp a global variable?
(1 answer)
Why can't const functions in Rust make calls to associated functions?
(1 answer)
How can you make a safe static singleton in Rust?
(3 answers)
How do I create a global, mutable singleton?
(7 answers)
Closed 3 years ago.
How do I initialize a BTreeMap within a const struct?
use std::collections::BTreeMap;
struct Book {
year: u16,
volume: u8,
amendment: u8,
contents: BTreeMap<String, String>,
}
const BOOK1: Book = Book {
year: 2019,
volume: 1,
amendment: 0,
contents: BTreeMap::new(), // Issue here
};
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src/lib.rs:14:15
|
14 | contents: BTreeMap::new(),
| ^^^^^^^^^^^^^^^
You can't. As of Rust 1.34.0, there is no function marked with const for BTreeMap. That's why you can't define a const BtreeMap at all.
The only way would be a static variable and the usage of the lazy_static crate.
use lazy_static::lazy_static; // 1.3.0
use std::collections::BTreeMap;
lazy_static! {
static ref BOOK1: Book = Book {
year: 2019,
volume: 1,
amendment: 0,
contents: BTreeMap::new()
};
}
This question already has answers here:
How can you make a safe static singleton in Rust?
(3 answers)
How do I create a global, mutable singleton?
(7 answers)
Closed 4 years ago.
Sometimes, it’s handy to have a few instances of a struct stored and accessible everywhere.
For instance, if I want to store some meta-data about a currency in a struct like this:
struct Currency {
name: &'static str,
iso_symbols: Vec<&'static str>
}
I would then create an instance of Currency for every major currency. As these property don’t change, it could be hard-coded, at least for some currencies.
I tried to use const, which would work without a Vec (the vec! macro does an allocation, which is not allowed in const).
const BTC: Currency = Currency {
name: "Bitcoin",
iso_symbols: vec!["BTC", "XBT"]
};
So what workaround would you suggest to store a bunch of instance of Currency (for EUR, USD, BTC…)?
Here, in the Rust Playground.
EDIT: My question is quite similar to this one. The only difference is that I don’t need a mutable singleton, so the “Non-answer answer” doesn’t apply, right? The lazy_static idea is great though!
It might be interesting to keep this question around since I didn’t searched with the keyword singleton and I may not be alone to miss this way to consider the problem.
As pointed out in the comments, the lazy_static crate works well.
pub struct Currency {
name: &'static str,
iso_symbols: Vec<&'static str>,
}
lazy_static! {
pub static ref BTC: Currency = Currency {
name: "Bitcoin",
iso_symbols: vec!["BTC", "XBT"]
};
}
fn main() {
println!("{} {:?}", BTC.name, BTC.iso_symbols);
}
We have this global (with pub) variable BTC I was looking for.
This question already has answers here:
How do I create a global, mutable singleton?
(7 answers)
How do I keep internal state in a WebAssembly module written in Rust?
(2 answers)
Closed 4 years ago.
I'm attempting to write a data store in Rust that receives objects from JavaScript across the wasm-bindgen boundary and stores them for later retrieval. This is a simplified version of what I was hoping would work:
static mut MAP: HashMap<i32, String> = HashMap::new();
#[wasm_bindgen]
pub fn add_value(index: i32, value: String) {
unsafe {
MAP.insert(index, value);
}
}
#[wasm_bindgen]
pub fn get_value(index: i32) -> String {
unsafe {
(*MAP.get(&index).unwrap()).clone()
}
}
However I get this error from the Rust compiler:
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
How can I store state so that subsequent calls across the wasm-bindgen boundary can retrieve previously stored values?