Popular New Releases in Rust
deno
v1.20.6
rust
Rust 1.60.0
alacritty
Alacritty Version 0.10.1
tauri
tauri-driver v0.1.2
bat
v0.20.0
Popular Libraries in Rust
by 996icu rust
258630 NOASSERTION
Repo for counting stars and contributing. Press F to pay respect to glorious developers.
by denoland rust
81698 MIT
A modern runtime for JavaScript and TypeScript.
by rust-lang rust
65482 NOASSERTION
Empowering everyone to build reliable and efficient software.
by alacritty rust
37538 Apache-2.0
A cross-platform, OpenGL terminal emulator.
by tauri-apps rust
36698 Apache-2.0
Build smaller, faster, and more secure desktop applications with a web frontend.
by sharkdp rust
33294 NOASSERTION
A cat(1) clone with wings.
by BurntSushi rust
27048 NOASSERTION
ripgrep recursively searches directories for a regex pattern while respecting your gitignore
by meilisearch rust
25990 MIT
Powerful, fast, and an easy to use search engine
by starship rust
24749 ISC
☄🌌️ The minimal, blazing-fast, and infinitely customizable prompt for any shell!
Trending New libraries in Rust
by AppFlowy-IO rust
20428 AGPL-3.0
AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.
by rome rust
18488 MIT
The Rome Toolchain. A linter, compiler, bundler, and more for JavaScript, TypeScript, HTML, Markdown, and CSS.
by AppFlowy-IO rust
16821 AGPL-3.0
AppFlowy is an open-source alternative to Notion. You are in charge of your data and customizations. Built with Flutter and Rust.
by bevyengine rust
15512 NOASSERTION
A refreshingly simple data-driven game engine built in Rust
by rustdesk rust
11657 GPL-3.0
Yet another remote desktop software
by helix-editor rust
8142 MPL-2.0
A post-modern modal text editor.
by extrawurst rust
7791 MIT
Blazing 💥 fast terminal-ui for git written in rust 🦀
by qarmin rust
6600 NOASSERTION
Multi functional app to find duplicates, empty folders, similar images etc.
by RustScan rust
6109 GPL-3.0
🤖 The Modern Port Scanner 🤖
Top Authors in Rust
1
119 Libraries
21460
2
107 Libraries
4
3
103 Libraries
2802
4
96 Libraries
1179
5
88 Libraries
4414
6
87 Libraries
12
7
86 Libraries
12617
8
86 Libraries
134
9
78 Libraries
34
10
78 Libraries
171439
1
119 Libraries
21460
2
107 Libraries
4
3
103 Libraries
2802
4
96 Libraries
1179
5
88 Libraries
4414
6
87 Libraries
12
7
86 Libraries
12617
8
86 Libraries
134
9
78 Libraries
34
10
78 Libraries
171439
Trending Kits in Rust
Regular expressions are useful tools for text manipulation and pattern matching. They consist of a combination of literal characters and metacharacters.
Regex metacharacters are special characters with a symbolic meaning in regular expressions. These metacharacters have a specific function or purpose within a regular expression pattern.
Example of Regex:
- ^ and $ anchor the regex at the start and end of the string, ensuring the entire string matches the pattern.
- [a-zA-Z0-9._%+-]+ matches the username part, allowing alphanumeric characters, dots, underscores, etc.
- @ is a literal character that must be present in the middle.
- [a-zA-Z0-9.-]+ matches the domain part before the dot. This allows alphanumeric characters and dots.
- \. is used to match a literal dot before the top-level domain (TLD).
- [a-zA-Z]{2,} matches the TLD, requiring at least two alphabetical characters.
In conclusion, regular expressions play a vital role in text processing and manipulation. Understanding regex provides a powerful task for the beginner or an experienced developer. Regex skill is particularly crucial in Python. It serves as a versatile and expressive mechanism for working with strings.
Fig: Preview of the output that you will get on running this code from your IDE.
Code
In this solution we are using Regex library of Python.
Instructions
Follow the steps carefully to get the output easily.
- Download and Install the PyCharm Community Edition on your computer.
- Open the terminal and install the required libraries with the following commands.
- Install Regex - pip install Regex.
- Create a new Python file on your IDE.
- Copy the snippet using the 'copy' button and paste it into your Python file.
- Run the current file to generate the output.
I hope you found this useful.
I found this code snippet by searching for 'python regex escaping meta characters among delimiters' in Kandi. You can try any such use case!
Environment Tested
I tested this solution in the following versions. Be mindful of changes when working with other versions.
- PyCharm Community Edition 2023.2
- The solution is created in Python 3.8 Version
- Regex 2023.10.3 Version.
Using this solution, we can be able to use metacharacters in python regex with simple steps. This process also facilities an easy way to use, hassle-free method to create a hands-on working version of code which would help us to use metacharacters in python regex.
Dependent Library
You can search for any dependent library on kandi like 'regex'.
FAQ
1. What are the Python regular expressions, and why are they important?
Python regular expressions, often referred to as regex or re are a powerful and flexible tool. Regular expressions are patterns that describe string sets. The Python re-module provides a set of functions to work with regular expressions. It allows developers to perform various text-processing tasks.
- Pattern Matching
- Text Validation
- String Manipulation
- Search and Extraction
- Complex Text Processing
- Cross-Language Compatibility
- Debugging and Troubleshooting
2. How do string literals work in Python when it comes to regex metacharacters?
Python string literals are a sequence of characters enclosed in quotes. Single quotes or double quotes define them. In Python, string literals are immutable and help with regular expressions. Patterns in strings are matched using regular expressions.
3. What is the best way to learn Python for those new to regex metacharacters?
The regular expressions and their metacharacters can seem challenging to its right. It becomes an essential and powerful skill for text processing in Python.
- Understand the Basics
- Start with Simple Patterns
- Learn Character Classes
- Quantifiers and Wildcards
- Anchors and Boundaries
- Grouping and Capturing
- Escape Metacharacters
- Practice Regularly
- Use Learning Resources
- Work on Real-World Examples
4. What role do escape sequences play in Python regular expression matching?
The sequences play a crucial role in Python regular expression matching. They help to handle special characters and metacharacters within regex patterns. Regular expressions of certain characters have special meanings and escape these characters. This is especially important in Python, where the backslash is also used as an escape literal.
5. What occurs while using the zero or more occurrences symbol in a Python regex pattern?
The zero or more occurrences symbol works inside a regular expression pattern. The quantifier specifies that the preceding character or group may appear zero. It allows for flexibility in matching patterns that have variable repetition.
Support
- For any support on kandi solution kits, please use the chat
- For further learning resources, visit the Open Weaver Community learning page
Regular expressions are a useful tool for matching patterns in strings. The re-module provides support for regular expressions.
Regular expressions are a concise and flexible means for matching strings of text. It is such as particular characters, words, or patterns of characters.
Key Concepts of Python Regex:
1.Pattern: A regular expression pattern is a text string describing a search pattern. It can include literal characters, metacharacters, and various special sequences.
2.Metacharacters: These are characters with a special meaning. Some common metacharacters.
- . (dot): Matches any character except a newline.
- ^: Anchors the regex at the start of the string.
- $: Anchors the regex at the end of the string.
- *: Represents 0 or more occurrences of previous character.
- +: Denotes 1 or more occurrences of the previous character.
- ?: Represents 0 or 1 occurrence of the preceding character.
- \: Escapes a metacharacter, allowing you to match it as a literal.
3.Character Classes: Character classes allow you to match any one of a set of characters.
- example, [aeiou] matches any vowel.
4.Quantifiers: Quantifiers specify the number of occurrences of a character or group.
- Examples include * (0 or more), + (1 or more), and {n} (exactly n).
5.Groups and Capturing: Parentheses () creates groups. They can also capture portions of the matched text.
- For example, (ab)+ would match "ab," "abab," etc., and (a)(b) would capture "a" and "b" separately.
6.Special Sequences: These are backslash-escaped sequences that have a special meaning.
- For example, \d matches any digit, \w matches any alphanumeric character, and \s matches.
In summary, regex is a fundamental tool for text processing and manipulation. It offers developers a concise and powerful means to work with patterns in textual data. It makes it an indispensable part of a programmer's toolkit. Understanding and mastering regular expressions can significantly enhance one's ability to work.
Fig: Preview of the output that you will get on running this code from your IDE.
Code
In this solution we are using Regex library of Python.
Instructions
Follow the steps carefully to get the output easily.
- Download and Install the PyCharm Community Edition on your computer.
- Open the terminal and install the required libraries with the following commands.
- Install Pyglet - pip install Pyglet.
- Create a new Python file on your IDE.
- Copy the snippet using the 'copy' button and paste it into your Python file.
- Remove only 24 and 29 lines from the code.
- Run the current file to generate the output.
I hope you found this useful.
I found this code snippet by searching for 'Searching a string with a Regex in Python' in Kandi. You can try any such use case!
Environment Tested
I tested this solution in the following versions. Be mindful of changes when working with other versions.
- PyCharm Community Edition 2023.2
- The solution is created in Python 3.8 Version
- Regex 2023.10.3 Version.
Using this solution, we can be able to use search function in python regex with simple steps. This process also facilities an easy way to use, hassle-free method to create a hands-on working version of code which would help us to use search function in python regex.
Dependent Library
You can search for any dependent library on kandi like 'regex'.
FAQ
1. What are regular expression patterns and how do they work in Python Re search?
Regular expression patterns are sequences of characters that define a search pattern. These patterns can include both literal characters and special characters. In Python, regular expression patterns are often used with the re module for searching it.
2. How does a regular Python string differ from pattern matches in Python Re search?
Regular Python string literals and regular expression patterns used in Python's re modules.
- Escaping
- Raw String Literal
- Metacharacters
- Quantifiers and Special Sequences
3. What are identifiers, and how do they help parse data when using Python Re search?
The identifiers are names given to entities like variables, functions, classes, and modules.
- It must start with a letter (a-z, A-Z) or an underscore (_).
- The remaining characters can be letters, digits (0-9), or underscores.
- Identifiers are case-sensitive (myVar and myvar are different).
4. How does the last matched capturing group refine results in Python Re search?
The regular expression pattern contains many capturing groups. It can access the text matched by the last capturing group. It does this using the special identifier \g<index> within the pattern itself.
- (\w+): Matches and captures one or more-word characters (letters, digits, or underscores).
- -: Matches a hyphen.
- (\d+): Matches and captures one or more digits.
- -: Matches another hyphen.
- (\w+): Matches and captures one or more-word characters.
5. What are effective tips for optimizing parser functions in Python Re search programs??
Creating efficient parser functions using Python's re module. This involves a combination of good practices, optimization techniques, and understanding regular expressions.
- Regular Expressions
- Raw String Literals
- Limit Greedy Quantifiers
- Optimize Character Classes
- Avoid Backtracking
- Grouping and Capturing
- Named Capturing Groups
- Profiling and Testing
- Third-Party Libraries
Support
- For any support on kandi solution kits, please use the chat
- For further learning resources, visit the Open Weaver Community learning page
Web3 has the underpinnings to provide for a genuinely democratic and privacy-focused World Wide Web! The early web was democratic and provided unprecedented access to information. However, given the nascent state, it was highly disorganized and provided inconsistent collaboration experiences. This led to the evolution of hyper-scale providers in Web 2.0, which brought in organization, and exciting ways of social and mobile collaboration. The downside of Web 2.0 is a very disproportionate imbalance in power resting with the big tech and social media companies and zero control with the consumers, who surprisingly are the content and data creators. These global concerns around the absolute dominance of tech platforms over consumers and privacy are driving Web 3. The core concepts of Web 3 that I found most defining are 1. A fully decentralized web, based on blockchain principles 2. The users generate tokens and in many ways are empowered to influence the platform 3. The users own and control their data While the Web 3.0 concept is a continuous work in progress, the recent focus on control, privacy, and the general prevalence of blockchain are making it closer to reality. Get ready and get started! The kandi kit on Getting Started with Web3 showcases Web3 libraries to interface with the blockchain easily.
Web3 Starter Libraries
re.split is a function in Python's re module that allows you to split a string based on a specified pattern. It uses a RE to define the splitting pattern.
It relies on a fixed delimiter. re.split is useful for cases to split strings using a pattern that goes beyond a simple fixed delimiter. It provides more flexibility in handling variations within the text. re.split() in Python is a method for splitting strings using a regular expression pattern.
Here are some common use cases:
- Splitting Strings into Lines
- Splitting by Many Delimiters
- Splitting Files into Chunks
- Limiting the Number of Splits
- Using Capture Groups
- Removing Empty Strings
When splitting strings, various options are available, each suited for different scenarios.
Here are a few methods:
- Using Default Delimiter: The simplest method involves splitting a string. This occurs using a default delimiter, such as a space or comma.
- Delimiter-Based Splitting: Specify a custom delimiter to split the string. Useful when the data has a consistent pattern.
- Regular Expressions (Regex): Regex provides powerful pattern matching for string splitting.
- Whitespace Splitting: Splits the string based on whitespace characters (spaces, tabs, line breaks).
- Limiting the Number of Splits: Some languages allow you to limit the number of splits. It provides control over the output.
- Partition Method: It splits a string into three parts based on a delimiter.
- Strtok Function: In languages like C or C++, this helps in splitting strings based on a delimiter.
- Splitting Lines: Often used for processing text files. It splits a string into lines using newline characters.
- Joining and Splitting: It allows for more complex operations. Those operations reverse the order of elements.
- CSV Parsing: Specific to handling CSV data. Used libraries like csv in Python provide convenient methods for parsing.
When using re.split in Python, consider these tips:
- Choose the Right Delimiter
- Escape Special Characters
- Handle Many Delimiters
- Consider Whitespace
- Handle Repetitive Delimiters
- Account for Leading and Trailing Delimiters
- Be Mindful of Empty Strings
- Use Non-Capturing Groups
- Test with Edge Cases
- Consider Alternative Approaches
In conclusion, Python's re.split offers enhanced string-splitting capabilities. It enables more sophisticated and flexible text processing. Its regex-based approach allows for precise pattern matching, facilitating complex parsing tasks. This can lead to cleaner, more efficient code, improved readability, and better maintenance. Embracing re.split empowers developers to handle diverse input scenarios with ease. This makes it a valuable tool for robust and adaptable codebases.
Fig: Preview of the output that you will get on running this code from your IDE.
Code
In this solution we are using regex library in Python.
Instructions
Follow the steps carefully to get the output easily.
- Download and Install the PyCharm Community Edition on your computer.
- Open the terminal and install the required libraries with the following commands.
- Create a new Python file on your IDE.
- Copy the snippet using the 'copy' button and paste it into your python file.
- Run the current file to generate the output.
I hope you found this useful.
I found this code snippet by searching for 'How to use split function in regex' in Kandi. You can try any such use case!
Environment Tested
I tested this solution in the following versions. Be mindful of changes when working with other versions.
- PyCharm Community Edition 2022.3.1
- The solution is created in Python 3.11.1 Version
- regex 1.0.0 Version
Using this solution, we can able to use split function in regex in python with simple steps. This process also facilities an easy way to use, hassle-free method to create a hands-on working version of code which would help us to use split function in regex in python.
Dependent Library
You can search for any dependent library on Kandi like 'regex'.
FAQ
1. What is a regular Python string literal, and how does it impact the re.split function?
A regular Python string literal is a sequence of characters in single (' '), double (" "), or triple ('' ''' or """ """) quotes. In the context of the re.split function, the regular string literal is the pattern. That pattern helps to identify the delimiter for splitting a string.
2. How do I use a regular expression cache to improve performance when using re.split?
To use this, you can compile your regular expression pattern using re.compile. This creates a compiled regular & reusable expression object. It reduces the overhead of recompiling the pattern for each split operation.
3. What are identifiers in relation to the re.split function?
Identifiers refer to the delimiters or patterns. It identifies where the string should split. These can be simple strings, depending on the desired splitting criteria.
4. How can I create a compiled regular expression object to use with the re.split function?
You can create a compiled regular expression object using the re.compile function.
For example:
import re
pattern = re.compile(r'\s+')
result = pattern.split("This is a sample string")
5. Is the re.split function part of the Python Standard Library, or is it an external library?
The re.split function is part of the Python Standard Library, the re module. It is not an external library, so you can use it without extra installations.
Support
- For any support on Kandi solution kits, please use the chat
- For further learning resources, visit the Open Weaver Community learning page
Trending Discussions on Rust
Why is Rust NLL not working for multiple borrows in the same statement?
Next failed to load SWC binary
Emulate BTreeMap::pop_last in stable Rust
Match ergonomics and & pattern
What is the built-in `#[main]` attribute?
Difference between `cargo doc` and `cargo rustdoc`
Unable to specify `edition2021` in order to use unstable packages in Rust
What is the idiomatic way to do something when an Option is either None, or the inner value meets some condition?
What is the official Rust guidance for interoperability with C++, in particular passing and returning structs as arguments?
Why does iteration over an inclusive range generate longer assembly in Rust?
QUESTION
Why is Rust NLL not working for multiple borrows in the same statement?
Asked 2022-Apr-12 at 00:43First, I tried something like this:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3
It can't be compiled because:
error[E0502]: cannot borrow `vec` as immutable because it is also borrowed as mutable
I thought that the Rust borrow checker could be smarter than this, so I found something called NLL, and it should solve this problem.
I tried the sample:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5
It could work, but why is it not working with rotate_right
? Both of them take a &mut self
. What's going on?
ANSWER
Answered 2022-Apr-12 at 00:43It is definitely an interesting one.
They are similar - but not quite the same. resize()
is a member of Vec
. rotate_right()
, on the other hand, is a method of slices.
Vec<T>
derefs to [T]
, so most of the time this does not matter. But actually, while this call:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6
Desugars to something like:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7
This call:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7vec.rotate_right(vec.len());
8
Is more like:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7vec.rotate_right(vec.len());
8<[i32]>::rotate_right(
9 <Vec<i32> as DerefMut>::deref_mut(&mut vec),
10 <Vec<i32>>::len(&vec),
11);
12
But in what order?
This is the MIR for rotate_right()
(simplified a lot):
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7vec.rotate_right(vec.len());
8<[i32]>::rotate_right(
9 <Vec<i32> as DerefMut>::deref_mut(&mut vec),
10 <Vec<i32>>::len(&vec),
11);
12fn foo() -> () {
13 _4 = <Vec<i32> as DerefMut>::deref_mut(move _5);
14 _6 = Vec::<i32>::len(move _7);
15 _2 = core::slice::<impl [i32]>::rotate_right(move _3, move _6);
16}
17
And this is the MIR for resize()
(again, simplified a lot):
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7vec.rotate_right(vec.len());
8<[i32]>::rotate_right(
9 <Vec<i32> as DerefMut>::deref_mut(&mut vec),
10 <Vec<i32>>::len(&vec),
11);
12fn foo() -> () {
13 _4 = <Vec<i32> as DerefMut>::deref_mut(move _5);
14 _6 = Vec::<i32>::len(move _7);
15 _2 = core::slice::<impl [i32]>::rotate_right(move _3, move _6);
16}
17fn foo() -> () {
18 _4 = Vec::<i32>::len(move _5);
19 _2 = Vec::<i32>::resize(move _3, move _4, const 0_i32);
20}
21
In the resize()
example, we first call Vec::len()
with a reference to vec
. This returns usize
. Then we call Vec::resize()
, when we have no outstanding references to vec
, so mutably borrowing it is fine!
However, with rotate_right()
, first we call <Vec<i32> as DerefMut>::deref_mut(&mut vec)
. This returns &mut [i32]
, with its lifetime tied to vec
. That is, as long as this reference (mutable reference!) is alive, we are not allowed to use have any other reference to vec
. But then we try to borrow vec
in order to pass the (shared, but it doesn't matter) reference to Vec::len()
, while we still need to use the mutable reference from deref_mut()
later, in the call to <[i32]>::rotate_right()
! This is an error.
This is because Rust defines an evaluation order for operands:
Expressions taking multiple operands are evaluated left to right as written in the source code.
Because vec.resize()
is actually (&mut *vec).rotate_right()
, we first evaluate the dereference+reference, then the arguments:
1let mut vec = vec![0];
2vec.rotate_right(vec.len());
3let mut vec = vec![0];
4vec.resize(vec.len(), 0);
5vec.resize(vec.len(), 0);
6<Vec<i32>>::resize(&mut vec, <Vec<i32>>::len(&vec), 0);
7vec.rotate_right(vec.len());
8<[i32]>::rotate_right(
9 <Vec<i32> as DerefMut>::deref_mut(&mut vec),
10 <Vec<i32>>::len(&vec),
11);
12fn foo() -> () {
13 _4 = <Vec<i32> as DerefMut>::deref_mut(move _5);
14 _6 = Vec::<i32>::len(move _7);
15 _2 = core::slice::<impl [i32]>::rotate_right(move _3, move _6);
16}
17fn foo() -> () {
18 _4 = Vec::<i32>::len(move _5);
19 _2 = Vec::<i32>::resize(move _3, move _4, const 0_i32);
20}
21let dereferenced_vec = &mut *vec;
22let len = vec.len();
23dereferencec_vec.rotate_right(len);
24
Which is obviously a violation of the borrow rules.
On the other hand, vec.resize(vec.len())
has no work to do on the callee (vec
), and so we first evaluate vec.len()
, and then the call itself.
Solving this is as easy as extracting the vec.len()
to a new line (new statement, to be precise), and the compiler also suggests that.
QUESTION
Next failed to load SWC binary
Asked 2022-Mar-22 at 05:46When trying to run the command using nextjs npm run dev shows error - failed to load SWC binary see more info here: https://nextjs.org/docs/messages/failed-loading-swc.
I've tried uninstalling node and reinstalling it again with version 16.13 but without success, on the vercel page, but unsuccessful so far. Any tips?
Also, I noticed it's a current issue on NextJS discussion page and it has to do with the new Rust-base compiler which is faster than Babel.
ANSWER
Answered 2021-Nov-20 at 13:57This worked as suggeted by nextJS docs but it takes away Rust compiler and all its benefits... Here is what I did for those who eventually get stuck...
Step 1. add this line or edit next.json.js
1{
2swcMinify: false // it should be false by default
3}
4
Step 2. add a ".babelrc" file to project root dir
Step 3. add this snippet to the new file ".babelrc"
1{
2swcMinify: false // it should be false by default
3}
4{
5"presets": ["next/babel"]
6}
7
Step 4, you need to run this command as steps 1-3 will remove SWC failed to load error but you will notice another error when you run the build command. So run this too
1{
2swcMinify: false // it should be false by default
3}
4{
5"presets": ["next/babel"]
6}
7npm install next@canary
8
hope this helps
QUESTION
Emulate BTreeMap::pop_last in stable Rust
Asked 2022-Mar-15 at 16:55In the current stable Rust, is there a way to write a function equivalent to BTreeMap::pop_last?
The best I could come up with is:
1fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
2where
3 K: Ord + Clone,
4{
5 let last = m.iter().next_back();
6 if let Some((k, _)) = last {
7 let k_copy = k.clone();
8 return m.remove_entry(&k_copy);
9 }
10 None
11}
12
It works, but it requires that the key is cloneable. BTreeMap::pop_last from Rust nightly imposes no such constraint.
If I remove the cloning like this
1fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
2where
3 K: Ord + Clone,
4{
5 let last = m.iter().next_back();
6 if let Some((k, _)) = last {
7 let k_copy = k.clone();
8 return m.remove_entry(&k_copy);
9 }
10 None
11}
12fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
13where
14 K: Ord,
15{
16 let last = m.iter().next_back();
17 if let Some((k, _)) = last {
18 return m.remove_entry(k);
19 }
20 None
21}
22
it leads to
1fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
2where
3 K: Ord + Clone,
4{
5 let last = m.iter().next_back();
6 if let Some((k, _)) = last {
7 let k_copy = k.clone();
8 return m.remove_entry(&k_copy);
9 }
10 None
11}
12fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
13where
14 K: Ord,
15{
16 let last = m.iter().next_back();
17 if let Some((k, _)) = last {
18 return m.remove_entry(k);
19 }
20 None
21}
22error[E0502]: cannot borrow `*m` as mutable because it is also borrowed as immutable
23 --> ...
24 |
25.. | let last = m.iter().next_back();
26 | -------- immutable borrow occurs here
27.. | if let Some((k, _)) = last {
28.. | return m.remove_entry(k);
29 | ^^------------^^^
30 | | |
31 | | immutable borrow later used by call
32 | mutable borrow occurs here
33
Is there a way to work around this issue without imposing additional constraints on map key and value types?
ANSWER
Answered 2022-Mar-15 at 16:55Is there a way to work around this issue without imposing additional constraints on map key and value types?
It doesn't appear doable in safe Rust, at least not with reasonable algorithmic complexity. (See Aiden4's answer for a solution that does it by re-building the whole map.)
But if you're allowed to use unsafe, and if you're determined enough that you want to delve into it, this code could do it:
1fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
2where
3 K: Ord + Clone,
4{
5 let last = m.iter().next_back();
6 if let Some((k, _)) = last {
7 let k_copy = k.clone();
8 return m.remove_entry(&k_copy);
9 }
10 None
11}
12fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
13where
14 K: Ord,
15{
16 let last = m.iter().next_back();
17 if let Some((k, _)) = last {
18 return m.remove_entry(k);
19 }
20 None
21}
22error[E0502]: cannot borrow `*m` as mutable because it is also borrowed as immutable
23 --> ...
24 |
25.. | let last = m.iter().next_back();
26 | -------- immutable borrow occurs here
27.. | if let Some((k, _)) = last {
28.. | return m.remove_entry(k);
29 | ^^------------^^^
30 | | |
31 | | immutable borrow later used by call
32 | mutable borrow occurs here
33// Safety: if key uses shared interior mutability, the comparison function
34// must not use it. (E.g. it is not allowed to call borrow_mut() on a
35// Rc<RefCell<X>> inside the key). It is extremely unlikely that such a
36// key exists, but it's possible to write it, so this must be marked unsafe.
37unsafe fn map_pop_last<K, V>(m: &mut BTreeMap<K, V>) -> Option<(K, V)>
38where
39 K: Ord,
40{
41 // We make a shallow copy of the key in the map, and pass a
42 // reference to the copy to BTreeMap::remove_entry(). Since
43 // remove_entry() is not dropping the key/value pair (it's returning
44 // it), our shallow copy will remain throughout the lifetime of
45 // remove_entry(), even if the key contains references.
46 let (last_key_ref, _) = m.iter().next_back()?;
47 let last_key_copy = ManuallyDrop::new(std::ptr::read(last_key_ref));
48 m.remove_entry(&last_key_copy)
49}
50
QUESTION
Match ergonomics and & pattern
Asked 2022-Mar-03 at 21:14Consider following code
1fn main() {
2 let s = (&&0,);
3 let (x,) = s; // &&i32
4 let (&y,) = s; // &i32
5 let (&&z,) = s; // i32
6
7 let t = &(&0,);
8 let (x,) = t; // &&i32
9 let (&y,) = t; // i32
10
11 let u = &&(0,);
12 let (x,) = u; // &i32
13 let (&y,) = u; // mismatched types expected type `{integer}` found reference `&_`
14}
15
Could someone explain, why &
pattern behaves differently in every case? I suppose it is tied somehow to match ergonomics, maybe some coercions come into play? But I can't wrap my head around it.
ANSWER
Answered 2022-Mar-03 at 21:14You are correct, this is due to match ergonomics. The first case should hopefully be self explanatory, but the second and third cases can be a bit counter-intuitive.
In the second case:
(x,)
is a non-reference pattern (see the second example in the RFC). Thet
tuple reference is dereferenced, andx
is bound as aref
as it also is a non-reference pattern. Note thatt.0
was a reference to begin with, thus resulting inx
being a double reference.(&y,)
is also a non-reference pattern. Thet
tuple is dereferenced again to a(&i32,)
. However,&y
is a reference pattern being matched to a&i32
reference. Hencey
is bound withmove
mode and is ani32
.
In the third case:
Using the same reasoning as the second case,
u
is dereferenced viaDeref
coercion to an(i32,)
, andx
, a non-reference pattern, is bound inref
mode. Hencex
is an&i32
.Again with the same reasoning as the second case,
u
is dereferenced to an(i32,)
. The&y
reference pattern is then matched to ani32
, a non-reference, which causes an error.
QUESTION
What is the built-in `#[main]` attribute?
Asked 2022-Feb-15 at 23:57I have been using the #[tokio::main]
macro in one of my programs. After importing main
and using it unqualified, I encountered an unexpected error.
1use tokio::main;
2
3#[main]
4async fn main() {}
5
1use tokio::main;
2
3#[main]
4async fn main() {}
5error[E0659]: `main` is ambiguous
6 --> src/main.rs:3:3
7 |
83 | #[main]
9 | ^^^^ ambiguous name
10 |
11 = note: ambiguous because of a name conflict with a builtin attribute
12 = note: `main` could refer to a built-in attribute
13
I've been scouring the documentation but I haven't been able to find this built-in #[main]
attribute described anywhere. The Rust Reference contains an index of built-in attributes. The index doesn't include #[main]
, though it does include an attribute named #[no_main]
.
I did a search of the rustlang/rust
repository, and found some code that seems related, but it seems to use a pair of macros named #[start]
and #[rustc_main]
, with no mention of #[main]
itself. (Neither of those macros appears to be usable on stable, with #[start]
emitting an error that it's unstable, and #[rustc_main]
emitting an error that it's only meant for internal use by the compiler.)
My guess from the name would have been that it's meant to mark a different function as an entry-point instead of main
, but it also doesn't seem to do that:
1use tokio::main;
2
3#[main]
4async fn main() {}
5error[E0659]: `main` is ambiguous
6 --> src/main.rs:3:3
7 |
83 | #[main]
9 | ^^^^ ambiguous name
10 |
11 = note: ambiguous because of a name conflict with a builtin attribute
12 = note: `main` could refer to a built-in attribute
13#[main]
14fn something_else() {
15 println!("this does not run");
16}
17
18fn main() {
19 println!("this runs");
20}
21
Rust Analyzer didn't have much to offer:
What does the built-in #[main]
attribute do, aside from conflicting with my imports? 😉
ANSWER
Answered 2022-Feb-15 at 23:57#[main]
is an old, unstable attribute that was mostly removed from the language in 1.53.0. However, the removal missed one line, with the result you see: the attribute had no effect, but it could be used on stable Rust without an error, and conflicted with imported attributes named main
. This was a bug, not intended behaviour. It has been fixed as of nightly-2022-02-10
and 1.59.0-beta.8
. Your example with use tokio::main;
and #[main]
can now run without error.
Before it was removed, the unstable #[main]
was used to specify the entry point of a program. Alex Crichton described the behaviour of it and related attributes in a 2016 comment on GitHub:
Ah yes, we've got three entry points. I.. think this is how they work:
- First,
#[start]
, the receiver ofint argc
andchar **argv
. This is literally the symbolmain
(or what is called by that symbol generated in the compiler).- Next, there's
#[lang = "start"]
. If no#[start]
exists in the crate graph then the compiler generates amain
function that calls this. This functions receives argc/argv along with a third argument that is a function pointer to the#[main]
function (defined below). Importantly,#[lang = "start"]
can be located in a library. For example it's located in the standard library (libstd).- Finally,
#[main]
, the main function for an executable. This is passed no arguments and is called by#[lang = "start"]
(if it decides to). The standard library uses this to initialize itself and then call the Rust program. This, if not specified, defaults tofn main
at the top.So to answer your question, this isn't the same as
#[start]
. To answer your other (possibly not yet asked) question, yes we have too many entry points.
QUESTION
Difference between `cargo doc` and `cargo rustdoc`
Asked 2022-Feb-15 at 14:32According to doc.rust-lang.org
build[s] a package's documentation, using specified custom flags
build[s] a package's documentation
What is the difference between the two? From what I understand cargo rustdoc
is just like cargo doc
, but it allows for more lints—for instance:
1#![deny(rustdoc::broken_intra_doc_links)]
2
Is this correct? Oddly enough, cargo rustdoc
will also fail in certain situations where cargo doc
doesn't. For instance
1#![deny(rustdoc::broken_intra_doc_links)]
2some/folder on some-branch [$!] via 🦀 v1.60.0-nightly
3❯ cargo doc
4 Finished dev [unoptimized + debuginfo] target(s) in 0.53s
5
6some/folder on some-branch [$!] via 🦀 v1.60.0-nightly
7❯ cargo rustdoc
8error: manifest path `some/folder/Cargo.toml` is a virtual manifest, but this command requires running against an actual package in this workspace
9
Also, cargo doc
does not support adding the -D
option, whereas cargo rustdoc
does.
1#![deny(rustdoc::broken_intra_doc_links)]
2some/folder on some-branch [$!] via 🦀 v1.60.0-nightly
3❯ cargo doc
4 Finished dev [unoptimized + debuginfo] target(s) in 0.53s
5
6some/folder on some-branch [$!] via 🦀 v1.60.0-nightly
7❯ cargo rustdoc
8error: manifest path `some/folder/Cargo.toml` is a virtual manifest, but this command requires running against an actual package in this workspace
9❯ cargo doc -- -D rustdoc::broken_intra_doc_links
10error: Found argument '-D' which wasn't expected, or isn't valid in this context
11
12USAGE:
13 cargo doc [OPTIONS]
14
15For more information try --help
16
ANSWER
Answered 2022-Jan-11 at 21:00Their relationship is like between cargo build
and cargo rustc
: cargo doc
performs all the usual work, for an entire workspace, including dependencies (by default). cargo rustdoc
allows you to pass flags directly to rustdoc, and only works for a single crate.
Here is the execution code for cargo rustdoc
. Here is the code for cargo doc
. The only differences is that cargo rustdoc
always specify to not check dependencies while cargo doc
allows you to choose (by default it does, but you can specify the flag --no-deps
), and that cargo rustc
allows you to pass flags directly to rustdoc with the flags after the --
.
QUESTION
Unable to specify `edition2021` in order to use unstable packages in Rust
Asked 2022-Feb-02 at 07:05I want to run an example via Cargo but I am facing an error:
1error: failed to parse manifest at `/Users/aviralsrivastava/dev/subxt/Cargo.toml`
2
The full stacktrace is:
1error: failed to parse manifest at `/Users/aviralsrivastava/dev/subxt/Cargo.toml`
2error: failed to parse manifest at `/Users/aviralsrivastava/dev/subxt/Cargo.toml`
3
4Caused by:
5 feature `edition2021` is required
6
7 The package requires the Cargo feature called `edition2021`, but that feature is not stabilized in this version of Cargo (1.56.0-nightly (b51439fd8 2021-08-09)).
8 Consider adding `cargo-features = ["edition2021"]` to the top of Cargo.toml (above the [package] table) to tell Cargo you are opting in to use this unstable feature.
9 See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#edition-2021 for more information about the status of this feature.
10
Based on the suggestion, I go ahead and modify the Cargo.toml:
1error: failed to parse manifest at `/Users/aviralsrivastava/dev/subxt/Cargo.toml`
2error: failed to parse manifest at `/Users/aviralsrivastava/dev/subxt/Cargo.toml`
3
4Caused by:
5 feature `edition2021` is required
6
7 The package requires the Cargo feature called `edition2021`, but that feature is not stabilized in this version of Cargo (1.56.0-nightly (b51439fd8 2021-08-09)).
8 Consider adding `cargo-features = ["edition2021"]` to the top of Cargo.toml (above the [package] table) to tell Cargo you are opting in to use this unstable feature.
9 See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#edition-2021 for more information about the status of this feature.
10 Consider adding `cargo-features = ["edition2021"]` to the top of Cargo.toml (above the [package] table) to tell Cargo you are opting in to use this unstable feature.
11diff --git a/Cargo.toml b/Cargo.toml
12index 26a02c7..186d09b 100644
13--- a/Cargo.toml
14+++ b/Cargo.toml
15@@ -1,6 +1,6 @@
16 [workspace]
17 members = [".", "cli", "codegen", "macro"]
18-
19+cargo-features = ["edition2021"]
20 [package]
21 name = "subxt"
22 version = "0.15.0"
23(END)
24
I still face the same error as if nothing was changed in the toml file.
How do I resolve the above error in order to use unstable packages?
ANSWER
Answered 2021-Dec-14 at 14:09Update the Rust to satisfy the new edition 2021.
rustup default nightly && rustup update
Thanks to @ken.
Yes, you can use the stable
channel too!
But I love nightly
personally.
QUESTION
What is the idiomatic way to do something when an Option is either None, or the inner value meets some condition?
Asked 2022-Jan-28 at 08:44Is there a more idiomatic way to express something like the following?
1fn main() {
2 let mut foo: Option<u8> = None;
3 match foo {
4 Some(foo_val) if ! (foo_val < 5) /* i.e. the negation of my acceptance condition */ => {}
5 _ => { foo.replace(5); }
6 }
7}
8
It seems like most of the time there's an alternative to having an arm that doesn't do anything, but I've been unable to find one for this particular case.
What I'd like to say is the more direct if foo.is_none() || /* some way to extract and test the inner value */ { ... }
, or perhaps some chaining trick that's eluding me.
ANSWER
Answered 2022-Jan-27 at 07:32There are many ways to do it. One of the simplest (and arguably most readable) is something like this:
1fn main() {
2 let mut foo: Option<u8> = None;
3 match foo {
4 Some(foo_val) if ! (foo_val < 5) /* i.e. the negation of my acceptance condition */ => {}
5 _ => { foo.replace(5); }
6 }
7}
8if foo.unwrap_or(0) < 5 {
9 ...
10}
11
The above will be true in both cases:
- when
foo
isSome
with a value smaller than5
; - when
foo
isNone
.
In some more complex scenarios, where the "default" value needs to be calculated and performance is critical, you might want to consider unwrap_or_else
.
As Lukas suggested, the map_or
method can also be used. Note that arguments passed to map_or
are eagerly evaluated, so if performance is critical, you might want to consider map_or_else
as an alternative.
QUESTION
What is the official Rust guidance for interoperability with C++, in particular passing and returning structs as arguments?
Asked 2022-Jan-26 at 23:08I'm trying to adapt some layers of existing C++ code to be used by Rust and apparently the way is through a C API.
For example, one function might return a struct as an object
1#pragma pack(push,4)
2struct Result {
3 char ch;
4 int32_t sum1;
5 int32_t sum2;
6};
7#pragma pack(pop)
8
9extern "C"
10Result
11muladd(int32_t a, int32_t b, int32_t c) {
12 return Result{1, a+b*c, a*b+c};
13}
14
And from Rust I'm doing
1#pragma pack(push,4)
2struct Result {
3 char ch;
4 int32_t sum1;
5 int32_t sum2;
6};
7#pragma pack(pop)
8
9extern "C"
10Result
11muladd(int32_t a, int32_t b, int32_t c) {
12 return Result{1, a+b*c, a*b+c};
13}
14#[repr(C,align(4))]
15pub struct Result {
16 pub ch: i8,
17 pub sum1: i32,
18 pub sum2: i32,
19}
20
21extern "C" {
22 pub fn muladd( a:i32, b:i32, c:i32 ) -> Result;
23}
24
25pub fn usemuladd( val: i32 ) -> i32 {
26 unsafe {
27 let res = muladd( val, val, val );
28 return res.sum1;
29 }
30}
31
I'm seeing odd results with respect to alignment and packing of structures. I have read that Rust can play around with structs, and neither ordering or packing are guaranteed.
It seems that using #[repr(C)]
and extern "C"
is the key to a happy compatibility layer. My question is then: can I trust that these two will get me solid through or there will always be unannounced edge cases that I have to worry about?
ANSWER
Answered 2022-Jan-21 at 01:15QUESTION
Why does iteration over an inclusive range generate longer assembly in Rust?
Asked 2022-Jan-15 at 11:19These two loops are equivalent in C++ and Rust:
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9pub fn sum1(num: u64) -> u64 {
10 let mut sum: u64 = 0;
11 for j in 0u64..=num {
12 sum += 1;
13 }
14 return sum;
15}
16
However the C++ version generates a very terse assembly:
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9pub fn sum1(num: u64) -> u64 {
10 let mut sum: u64 = 0;
11 for j in 0u64..=num {
12 sum += 1;
13 }
14 return sum;
15}
16sum1(unsigned long): # @sum1(unsigned long)
17 xor eax, eax
18.LBB0_1: # =>This Inner Loop Header: Depth=1
19 add rax, 1
20 cmp rax, rdi
21 jbe .LBB0_1
22 ret
23
while Rust's version is very long with two checks in the loop instead of one:
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9pub fn sum1(num: u64) -> u64 {
10 let mut sum: u64 = 0;
11 for j in 0u64..=num {
12 sum += 1;
13 }
14 return sum;
15}
16sum1(unsigned long): # @sum1(unsigned long)
17 xor eax, eax
18.LBB0_1: # =>This Inner Loop Header: Depth=1
19 add rax, 1
20 cmp rax, rdi
21 jbe .LBB0_1
22 ret
23example::sum1:
24 xor eax, eax
25 xor ecx, ecx
26.LBB0_1:
27 mov rdx, rcx
28 cmp rcx, rdi
29 adc rcx, 0
30 add rax, 1
31 cmp rdx, rdi
32 jae .LBB0_3
33 cmp rcx, rdi
34 jbe .LBB0_1
35.LBB0_3:
36 ret
37
Godbolt: https://godbolt.org/z/xYW94qxjK
What is Rust intrinsically trying to prevent that C++ is carefree about?
ANSWER
Answered 2022-Jan-12 at 10:20Overflow in the iterator state.
The C++ version will loop forever when given a large enough input:
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9pub fn sum1(num: u64) -> u64 {
10 let mut sum: u64 = 0;
11 for j in 0u64..=num {
12 sum += 1;
13 }
14 return sum;
15}
16sum1(unsigned long): # @sum1(unsigned long)
17 xor eax, eax
18.LBB0_1: # =>This Inner Loop Header: Depth=1
19 add rax, 1
20 cmp rax, rdi
21 jbe .LBB0_1
22 ret
23example::sum1:
24 xor eax, eax
25 xor ecx, ecx
26.LBB0_1:
27 mov rdx, rcx
28 cmp rcx, rdi
29 adc rcx, 0
30 add rax, 1
31 cmp rdx, rdi
32 jae .LBB0_3
33 cmp rcx, rdi
34 jbe .LBB0_1
35.LBB0_3:
36 ret
37#include <cstdint>
38
39[[gnu::noinline]]
40std::uint64_t sum1(std::uint64_t n) {
41 std::uint64_t sum = 0;
42 for (std::uint64_t j = 0; j <= n; ++j) {
43 sum += 1;
44 }
45 return sum;
46}
47
48#include <iostream>
49
50int main() {
51 std::cout << sum1(UINT64_C(0xffffffff'ffffffff)) << std::endl;
52
53 return 0;
54}
55
This is because when the loop counter j
finally reaches 0xffffffff'ffffffff
, incrementing it wraps around to 0, which means the loop invariant j <= n
is always fulfilled and the loop never exits.
Strictly speaking, invoking sum1
with 0xffffffff'ffffffff
infamously triggers undefined behaviour, though not because of overflow itself, but since infinite loops without externally-visible side effects are UB ([intro.progress]/1). This is why I applied the [[gnu::noinline]]
attribute to the function to prevent the compiler from taking ‘advantage’ of that in optimisation passes.
The Rust version, on the other hand, is not only perfectly well-defined, but iterates exactly as many times as the cardinality of the range:
1#include <cstdint>
2uint64_t sum1(uint64_t n) {
3 uint64_t sum = 0;
4 for (uint64_t j = 0; j <= n; ++j) {
5 sum += 1;
6 }
7 return sum;
8}
9pub fn sum1(num: u64) -> u64 {
10 let mut sum: u64 = 0;
11 for j in 0u64..=num {
12 sum += 1;
13 }
14 return sum;
15}
16sum1(unsigned long): # @sum1(unsigned long)
17 xor eax, eax
18.LBB0_1: # =>This Inner Loop Header: Depth=1
19 add rax, 1
20 cmp rax, rdi
21 jbe .LBB0_1
22 ret
23example::sum1:
24 xor eax, eax
25 xor ecx, ecx
26.LBB0_1:
27 mov rdx, rcx
28 cmp rcx, rdi
29 adc rcx, 0
30 add rax, 1
31 cmp rdx, rdi
32 jae .LBB0_3
33 cmp rcx, rdi
34 jbe .LBB0_1
35.LBB0_3:
36 ret
37#include <cstdint>
38
39[[gnu::noinline]]
40std::uint64_t sum1(std::uint64_t n) {
41 std::uint64_t sum = 0;
42 for (std::uint64_t j = 0; j <= n; ++j) {
43 sum += 1;
44 }
45 return sum;
46}
47
48#include <iostream>
49
50int main() {
51 std::cout << sum1(UINT64_C(0xffffffff'ffffffff)) << std::endl;
52
53 return 0;
54}
55use std::num::Wrapping;
56
57fn sum1(num: u64) -> u64 {
58 let mut sum = Wrapping(0);
59 for _ in 0..=num {
60 sum += Wrapping(1);
61 }
62 return sum.0;
63}
64
65fn main() {
66 println!("{}", sum1(0xffffffff_ffffffff));
67}
68
The above program (slightly modified to avoid getting bogged down in debug versus release mode differences with respect to the summation) will terminate after exactly 18446744073709551616 iterations and print 0; the Rust version carefully maintains iterator state so that overflow does not happen in the iterator.
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Rust
Tutorials and Learning Resources are not available at this moment for Rust