String behaves weird in rust [closed] - rust

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
let type1 = "Hello";
let mut type2 = String::from("World");
type2.push('!'); //Push can only add one single char
type2.push_str(" from Rust"); // push_str adds a string
let len = type2.len(); //Length of type2
let capacity = type2.capacity(); //Capacity in bytes
let contains = type2.contains("world"); //If contains sub string
println!("{:?}", (type1, type2, len, capacity, contains));
for words in type2.split_whitespace(){
println!("{}",words);
}
This code is giving error but if I remove the print it works just fine

In this line:
println!("{:?}", (type1, type2, len, capacity, contains));
You need to change type2 to &type2.
What you find "weird" has nothing to do with strings but the ownership/borrowing model in Rust. If you want to program in Rust, I strongly suggest you don't skip this crucial part of the language. You can start from here. Also, pay close attention to the compiler error messages. The Rust compiler usually emits incredibly accurate and useful error messages.

Related

How can I debug some Rust code to find out why the "if" statement doesn't run? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
This code is what I made from looking at the book "Hands-on Rust", it's basically a copy of the code from the "Searching an Array" part. I don't know why the "if valid" statement doesn't run even though the variable should be set to true.
use std::io::stdin;
fn main() {
println!("Please enter the key"); //prints the string
let mut enter = String::new(); //initiates the changeable variable "enter"
stdin().read_line(&mut enter).expect(r#"invalid key"#); //allows user input and reads the input to assign into the "enter" variable
enter.trim().to_lowercase(); //trims the "enter" variable out of non-letter inputs and turns them into lowercase
let key_list = ["1", "2", "3"]; //the input needed to get the desired output
let mut valid = false; //initiates the "valid" variable to false
for key in &key_list { //runs the block of code for each item in the "key_list" array
if key == &enter { //runs the block of code if the variable "enter" matches the contents of the array "key_list"
valid = true //turns the "valid" variable into true
}
};
if valid { //it will run the block of code if the variable valid is true
println!("very nice, {}", enter) //it prints the desired output
} else { //if the if statement does not fulfill the condition, the else statement's block of code will run
println!("key is either incorrect or the code for this program sucks, your input is {}", enter) //the failure output
}
}
Please pardon the absurd number of comments if it annoyed you. I did it to try and find where the bad part is.
There's a really cool macro called dbg! I love to use. It's like println! on steroids. You can wrap it around pretty much any variable, expression, or even sub-expression and it'll print the code inside it, the value, and the source location.
Let's add it to the loop and see what's going on:
for key in &key_list {
if dbg!(key) == dbg!(&enter) {
valid = true
}
};
Here's what I see:
Please enter the key
1
[src/main.rs:10] key = "1"
[src/main.rs:10] &enter = "1\n"
[src/main.rs:10] key = "2"
[src/main.rs:10] &enter = "1\n"
[src/main.rs:10] key = "3"
[src/main.rs:10] &enter = "1\n"
Ah! enter didn't actually get trimmed. It's still got the trailing newline. Hm, why is that? Let's take a look at the trim method:
pub fn trim(&self) -> &str
It looks like it returns a new &str slice rather than modifying the input string. We know it can't change it in place because it doesn't take &mut self.
to_lowercase is the same:
pub fn to_lowercase(&self) -> String
The fix:
let enter = enter.trim().to_lowercase();
The problem is that stdin().read_line() returns the input with a trailing newline, but str.trim() and str.to_lowercase() does not mutate the original str. You have to assign it back to enter:
enter = enter.trim().to_lowercase();
You could have spotted it by printing println!("your input is {:?}", enter) with the Debug format specifier, or the other option suggested in John's answer.

How to make aritmetic operations on Balance numbers to avoid overflow in NEAR smart contracts?

I want to do the following operation on Balance (u128) numbers in NEAR smart contract using Rust:
a*b / (a+b)
To avoid overflow I need to convert the type to a type that supports bigger numbers. What's the proper way to do it?
I found a construct_uint! macro. Is this a proper way to do or there is a better way?
construct_uint! {
/// 256-bit unsigned integer.
pub struct u256(4);
}
...
let aB = u256::from(a);
let bB = u256::from(b);
return (aB*bB / (aB+bB)).as_u128();
For the underflow part, please see saturating_sub:
https://doc.rust-lang.org/std/primitive.u128.html#method.saturating_sub

I need to know how to use popen to call the program bc, then how to give bc an equation from a string

I've been looking up the basics of bc and popen for hours now, and nothing can definitively tell me how I can use them together in a script. I am asking here not because I want some encouragement and reassurance that breaking down the problem will help me solve it. I need to know these specific things, because I cannot find this information anywhere, and I do not have the time, energy, or patience to beat my head against a wall for hours.
I am trying to write a code that can recieve an equation as a string, and this equation will be random, so the best way to solve it is to give it to bc. I also know that it will be in a format in the string that bc can undertand.
So far, I have this:
{
FILE *eq;
char eqstr[256];
char cmd[256];
eq = popen("bc *", "r");
if(eq == NULL)
{
exit(1);
}
while(fgets(eqstr, sizeof(eqstr), eq) != NULL)
{
strcpy(cmd, "echo '");
strcat(cmd, eqstr);
strcat(cmd, "' | bc");
}
pclose(eq);
return 0;
}
I need it to not print the result in the terminal, but to return the result to the code to be compared with the correct answer. The instructions and methodology of the test are extremely vague, so I have no clue how I check that the answer is right. This is a small part of a much larger code that is causing me so much grief.
If you can't show me an example code that solves my problem, at least recommend a website I can look at that might have the answers.

How do I convert a Rust numeric type but only if it fits? [duplicate]

This question already has an answer here:
How do I convert between numeric types safely and idiomatically?
(1 answer)
Closed 3 years ago.
I want the following
(2u128.pow(x)) as u64
but such that it succeeds for x < 64 and fails for x >= 64.
As you correctly pointed out yourself, you should use TryFrom, but you should also make sure the exponentiation itself doesn't overflow, by using u128::checked_pow instead of u128::pow:
use std::convert::TryFrom;
let x = 129;
let y = 2u128.checked_pow(x).expect("Number too big for exponentiation");
let z = u64::try_from(y).expect("Number too big for cast");
(playground link)
Okay, found the answer, there is TryFrom.
use std::convert::TryFrom;
u64::try_from(2u128.pow(x)).expect("Number too big for cast.")
from here which I somehow missed with my first search.

Warning function should have a snake case identifier on by default

I'm trying to figure out what this warning actually means. The program works perfectly but during compile I get this warning:
main.rs:6:1: 8:2 warning: function 'isMultiple' should have a snake case identifier,
#[warn(non_snake_case_functions)] on by default
the code is very simple:
/*
Find the sum of all multiples of 3 or 5 below 1000
*/
fn isMultiple(num: int) -> bool {
num % 5 == 0 || num % 3 == 0
}
fn main() {
let mut sum_of_multiples = 0;
//loop from 0..999
for i in range(0,1000) {
sum_of_multiples +=
if isMultiple(i) {
i
}else{
0
};
}
println!("Sum is {}", sum_of_multiples);
}
You can turn it off by including this line in your file. Check out this thread
#![allow(non_snake_case)]
Rust style is for functions with snake_case names, i.e. the compiler is recommending you write fn is_multiple(...).
My take on it is that programmers have been debating the case of names and other formatting over and over and over again, for decades. Everyone has their preferences, they are all different.
It's time we all grew up and realized that it's better we all use the same case and formatting. That makes code much easier to read for everyone in the long run. It's time to quit the selfish bickering over preferences. Just do as everyone else.
Personally I'm not much into underscores so the Rust standard upset me a bit. But I'm prepared to get use to it. Wouldn't it be great if we all did that and never had to waste time thinking and arguing about it again.
To that end I use cargo-fmt and clippy and I accept whatever they say to do. Job done, move on to next thing.
There is a method in the Rust convention:
Structs get camel case.
Variables get snake case.
Constants get all upper case.
Makes it easy to see what is what at a glance.
-ZiCog
Link to thread : https://users.rust-lang.org/t/is-snake-case-better-than-camelcase-when-writing-rust-code/36277/2

Resources