问题
I wrote a Rust library. I heard about the no_std
feature and noticed that my library does not use anything from std
that isn't offered by core and alloc. So in theory I could just add the #![no_std]
attribute and change a few imports.
But I wonder how this influences the users of my library. Of course, my hope is that by using #![no_std]
, users in no_std
environments can use my crate as well. That's good, of course. But: do users of my library have any disadvantage from my library being no_std
? For example, are they forced to also use #![no_std]
? That would be bad. I wonder because most crates hide no_std
compatibility behind a Cargo feature. And I actually couldn't find anything about this question online.
If there are no disadvantages from using #![no_std]
, then every crate who can work without std
should add that attribute, right?
回答1:
For example, are they forced to also use
#![no_std]
?
Not at all. The dependent crate (that is, the crate/project which will consume your crate) will know to find the core
crate required by your dependency, and one will be free to use it as if no_std
was ever involved. The main difference comes from what to expect from this dependency and how many other crates can use it. In other words, the set of crates compatible with your dependency should always be a superset if that dependency is prepared for no_std
.
The readme of KodrAus/rust-nostd, an example of using and testing no_std
in a library, also recommends using no_std
whenever possible for maximum compatibility:
The current design of Rust's standard library is split into a few layers, each building on the assumed platform capabilities of the one below. There's:
std
: the full standard library assumes the presence of threads, a filesystem, and networking. [...]alloc
: the collections layer builds on the core by assuming runtime support for dynamic memory allocation.core
: the core layer makes no (well, not very many) assumptions about the > underlying platform. Just about any target that can run Rust code is supported by core.So when you're designing your library you can make it maximally portable by targeting the lowest layer of the standard library that you can.
The reason some crates put no_std
behind a Cargo feature is because the crate may contain some opt-in functionalities which do require std
, or at the very least alloc
. By conditioning on Cargo features, environments without the standard library can still use the crate, whereas those with std
or alloc
can use an extended API of the crate. An example of "lib.rs" that shows this capability can be seen below.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "alloc")]
extern crate alloc;
pub fn foo_into_slice(slice: &mut [u8]) { unimplemented!() }
/// Vec requires alloc
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "alloc")]
pub fn foo_into_vec(vec: &mut Vec<u8>) { unimplemented!() }
来源:https://stackoverflow.com/questions/57611219/when-adding-no-std-to-a-library-are-there-any-disadvantages-or-complicati