Table of Contents
rustlings
conversions
as
fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>();
total / values.len() as f64
}
frominto
struct Person{}
impl From<&str> for Person {
fn from(s: &str) -> Person {
}
}
// then you can use
let p = Person::from("Mark,20");
fromstr
//可以自定义错误
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
}
}
tryfrominto
// 与from类似,但可以定义转换错误处理
// Tuple implementation
// https://doc.rust-lang.org/std/convert/trait.TryFrom.html
// Tuple implementation
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
let red = u8::try_from(tuple.0).map_err(|e| IntoColorError::IntConversion)?;
let green = u8::try_from(tuple.1).map_err(|e| IntoColorError::IntConversion)?;
let blue = u8::try_from(tuple.2).map_err(|e| IntoColorError::IntConversion)?;
Ok(Color { red, green, blue })
}
}
//可见,从i16->u8 可以使用 u8::try_from(i16)
asrefmut
https://doc.rust-lang.org/std/convert/trait.AsRef.html
unsafe
modify by address
raw pointer to ref
pub struct Adapter<T: Driver>(T); impl<T: Driver> driver::DriverOps for Adapter<T> { type RegType = bindings::pci_driver; unsafe fn register( reg: *mut bindings::pci_driver, ) -> Result { // SAFETY: By the safety requirements of this function (defined in the trait definition), // `reg` is non-null and valid. let pdrv: &mut bindings::pci_driver = unsafe { &mut *reg }; pdrv.name = name.as_char_ptr(); //... } }
//linux/rust/kernel/net.rs
unsafe extern "C" fn get_stats64_callback(
netdev: *mut bindings::net_device,
storage: *mut bindings::rtnl_link_stats64,
) {
// SAFETY: The C API guarantees that `net_device` isn't released while this function is running.
let dev = unsafe { Device::from_ptr(netdev) };
}
impl Device {
/// # Safety
///
/// The caller must ensure that `ptr` is valid and remains valid for the lifetime of the
/// returned [`Device`] instance.
pub(crate) unsafe fn from_ptr<'a>(ptr: *const bindings::net_device) -> &'a Device {
// SAFETY: The safety requirements guarantee the validity of the dereference, while the
// `Device` type being transparent makes the cast ok.
unsafe { &*ptr.cast() }
}
}
ref to raw pointer
//linux/rust/kernel/net.rs impl<T: NapiPoller> NapiAdapter<T> { /// Creates a new Napi object. pub fn add_weight(dev: &Device, weight: i32) -> Result<Pin<UniqueArc<Napi>>> { let mut napi = Pin::from(UniqueArc::try_new(Napi::new())?); unsafe { bindings::netif_napi_add_weight( &*dev as *const Device as *mut bindings::net_device, napi.as_mut().0.get(), Some(Self::poll_callback), weight, ) } Ok(napi) } }
&[u8] to core::ffi::cchar
#[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))]
unsafe fn printk(&self, klevel: &[u8], msg: fmt::Arguments<'_>) {
// SAFETY: `klevel` is null-terminated and one of the kernel constants. `self.raw_device`
// is valid because `self` is valid. The "%pA" format string expects a pointer to
// `fmt::Arguments`, which is what we're passing as the last argument.
#[cfg(CONFIG_PRINTK)]
unsafe {
bindings::_dev_printk(
klevel as *const _ as *const core::ffi::c_char,
self.raw_device(),
c_str!("%pA").as_char_ptr(),
&msg as *const _ as *const core::ffi::c_void,
)
};
}
raw pointer to box
/// # Safety
///
/// The `ptr` must contain an owned box of `Foo`.
unsafe fn raw_pointer_to_box(ptr: *mut Foo) -> Box<Foo> {
// SAFETY: The `ptr` contains an owned box of `Foo` by contract. We
// simply reconstruct the box from that pointer.
let mut ret: Box<Foo> = unsafe { Box::from_raw(ptr) };
ret
}
build.rs
set env
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(); // What's the use of this timestamp here?
let your_command = format!(
"rustc-env=TEST_FOO={}",
timestamp
);
println!("cargo:{}", your_command);
set feature
// In tests8, we should enable "pass" feature to make the
// testcase return early. Fill in the command to tell
// Cargo about that.
let your_command = "rustc-cfg=feature=\"pass\"";
println!("cargo:{}", your_command);
extern
//提供ABI接口
mod Foo {
// No `extern` equals `extern "Rust"`.
#[no_mangle]
fn my_demo_function(a: u32) -> u32 {
a
}
#[no_mangle]
fn my_demo_function_alias(a: u32) -> u32{
my_demo_function(a)
}
}
//使用ABI
extern "Rust" {
fn my_demo_function(a: u32) -> u32;
fn my_demo_function_alias(a: u32) -> u32;
}
算法
二叉搜索树
https://www.hello-algo.com/chapter_tree/binary_search_tree/
**