81.宏函数里面的不同的匹配规则需要使用分号隔开
// macros4.rs
//
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
#[rustfmt::skip]
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
($val:expr) => {
println!("Look at this other macro: {}", $val);
};
}
fn main() {
my_macro!();
my_macro!(7777);
}
82.使用内部封装好的宏来替代某些常数
// clippy1.rs
//
// The Clippy tool is a collection of lints to analyze your code so you can
// catch common mistakes and improve your Rust code.
//
// For these exercises the code will fail to compile when there are clippy
// warnings check clippy's suggestions from the output to solve the exercise.
//
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::f32;
fn main() {
let pi = f32::consts::PI;
// 3.14f32;
let radius = 5.00f32;
let area = pi * f32::powi(radius, 2);
println!(
"The area of a circle with radius {:.2} is {:.5}!",
radius, area
)
}
83.if let回顾
// clippy2.rs
//
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
// hint.
// I AM DONE
fn main() {
let mut res = 42;
let option = Some(12);
if let Some(x)=option {
res += x;
}
println!("{}", res);
}
84.按照提示修改
这题说明 resize是原地操作 没有返回值
交换值必须要借助中间变量
// clippy3.rs
//
// Here's a couple more easy Clippy fixes, so you can see its utility.
//
// Execute `rustlings hint clippy3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#[allow(unused_variables, unused_assignments)]
fn main() {
let my_option: Option<()> = None;
// if my_option.is_none() {
// my_option.unwrap();
// }
let my_arr = &[
-1, -2, -3,
-4, -5, -6,
];
println!("My array! Here it is: {:?}", my_arr);
let my_empty_vec = vec![1, 2, 3, 4, 5];
println!("This Vec is empty, see? {:?}", my_empty_vec);
let mut value_a = 45;
let mut value_b = 66;
// Let's swap these two!
let mut temp =0;
temp=value_a;
value_a = value_b;
value_b = temp;
println!("value a: {}; value b: {}", value_a, value_b);
}
85.使用as强制转换类型
// using_as.rs
//
// Type casting in Rust is done via the usage of the `as` operator. Please note
// that the `as` operator is not only used when type casting. It also helps with
// renaming imports.
//
// The goal is to make sure that the division does not fail to compile and
// returns the proper type.
//
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>();
total / values.len() as f64
}
fn main() {
let values = [3.5, 0.3, 13.0, 11.7];
println!("{}", average(&values));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn returns_proper_type_and_value() {
assert_eq!(average(&[3.5, 0.3, 13.0, 11.7]), 7.125);
}
}
86.大佬的奇特匹配orz
这题看了大佬的写法,太beautiful了(只有9行)
// from_into.rs
//
// The From trait is used for value-to-value conversions. If From is implemented
// correctly for a type, the Into trait should work conversely. You can read
// more about it at https://doc.rust-lang.org/std/convert/trait.From.html
//
// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)]
struct Person {
name: String,
age: usize,
}
// We implement the Default trait to use it as a fallback
// when the provided string is not convertible into a Person object
impl Default for Person {
fn default() -> Person {
Person {
name: String::from("John"),
age: 30,
}
}
}
// Your task is to complete this implementation in order for the line `let p =
// Person::from("Mark,20")` to compile Please note that you'll need to parse the
// age component into a `usize` with something like `"4".parse::<usize>()`. The
// outcome of this needs to be handled appropriately.
//
// Steps:
// 1. If the length of the provided string is 0, then return the default of
// Person.
// 2. Split the given string on the commas present in it.
// 3. Extract the first element from the split operation and use it as the name.
// 4. If the name is empty, then return the default of Person.
// 5. Extract the other element from the split operation and parse it into a
// `usize` as the age.
// If while parsing the age, something goes wrong, then return the default of
// Person Otherwise, then return an instantiated Person object with the results
// I AM NOT DONE
impl From<&str> for Person {
fn from(s: &str) -> Person {
let mut iter=s.trim().split(',');
let name=iter.next().unwrap_or_default();
let age = iter.next().and_then(|x| x.parse::<usize>().ok()).unwrap_or_default();
match (name,age,iter.next().is_some()) {
("",_,_) =>Person::default(),
(_,0,_) => Person::default(),
(_,_,true) =>Person::default(),
(name,age,_) =>Person{name:name.to_string(),age},
}
}
}
fn main() {
// Use the `from` function
let p1 = Person::from("Mark,20");
// Since From is implemented for Person, we should be able to use Into
let p2: Person = "Gerald,70".into();
println!("{:?}", p1);
println!("{:?}", p2);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default() {
// Test that the default person is 30 year old John
let dp = Person::default();
assert_eq!(dp.name, "John");
assert_eq!(dp.age, 30);
}
#[test]
fn test_bad_convert() {
// Test that John is returned when bad string is provided
let p = Person::from("");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_good_convert() {
// Test that "Mark,20" works
let p = Person::from("Mark,20");
assert_eq!(p.name, "Mark");
assert_eq!(p.age, 20);
}
#[test]
fn test_bad_age() {
// Test that "Mark,twenty" will return the default person due to an
// error in parsing age
let p = Person::from("Mark,twenty");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_comma_and_age() {
let p: Person = Person::from("Mark");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_age() {
let p: Person = Person::from("Mark,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name() {
let p: Person = Person::from(",1");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_age() {
let p: Person = Person::from(",");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_invalid_age() {
let p: Person = Person::from(",one");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,man");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
}
下面是我自己的丑陋的写法
// from_into.rs
//
// The From trait is used for value-to-value conversions. If From is implemented
// correctly for a type, the Into trait should work conversely. You can read
// more about it at https://doc.rust-lang.org/std/convert/trait.From.html
//
// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)]
struct Person {
name: String,
age: usize,
}
// We implement the Default trait to use it as a fallback
// when the provided string is not convertible into a Person object
impl Default for Person {
fn default() -> Person {
Person {
name: String::from("John"),
age: 30,
}
}
}
// Your task is to complete this implementation in order for the line `let p =
// Person::from("Mark,20")` to compile Please note that you'll need to parse the
// age component into a `usize` with something like `"4".parse::<usize>()`. The
// outcome of this needs to be handled appropriately.
//
// Steps:
// 1. If the length of the provided string is 0, then return the default of
// Person.
// 2. Split the given string on the commas present in it.
// 3. Extract the first element from the split operation and use it as the name.
// 4. If the name is empty, then return the default of Person.
// 5. Extract the other element from the split operation and parse it into a
// `usize` as the age.
// If while parsing the age, something goes wrong, then return the default of
// Person Otherwise, then return an instantiated Person object with the results
impl From<&str> for Person {
fn from(s: &str) -> Person {
let dataList:Vec<&str> =s.split(',').collect();
println!("{:?}",dataList);
// 数据量不对
if dataList.len() != 2 || dataList[0]=="" || dataList[1]=="" {
Person {
name: String::from("John"),
age: 30,
}
}
else {
if dataList[1].chars().all(|x| x.is_digit(10)) {
let uAge:usize = dataList[1].parse().unwrap();
Person {
name: dataList[0].to_string(),
age: uAge,
}
}
// 数据格式不对
else {
Person {
name: String::from("John"),
age: 30,
}
}
}
}
}
fn main() {
// Use the `from` function
let p1 = Person::from("Mark,20");
// Since From is implemented for Person, we should be able to use Into
let p2: Person = "Gerald,70".into();
println!("{:?}", p1);
println!("{:?}", p2);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default() {
// Test that the default person is 30 year old John
let dp = Person::default();
assert_eq!(dp.name, "John");
assert_eq!(dp.age, 30);
}
#[test]
fn test_bad_convert() {
// Test that John is returned when bad string is provided
let p = Person::from("");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_good_convert() {
// Test that "Mark,20" works
let p = Person::from("Mark,20");
assert_eq!(p.name, "Mark");
assert_eq!(p.age, 20);
}
#[test]
fn test_bad_age() {
// Test that "Mark,twenty" will return the default person due to an
// error in parsing age
let p = Person::from("Mark,twenty");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_comma_and_age() {
let p: Person = Person::from("Mark");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_age() {
let p: Person = Person::from("Mark,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name() {
let p: Person = Person::from(",1");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_age() {
let p: Person = Person::from(",");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_missing_name_and_invalid_age() {
let p: Person = Person::from(",one");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,man");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
}
87.对字符串进行合法判断
用我丑陋的写法写模拟orz,这题看看题目意思,知道大概要对字符串处理
正常返回Ok
错误返回错误类型
主要是凭感觉写的,这里面应该是通过系统库FromStr在创建的时候自动调用from_str来进行初始化,返回一个Person对象
// from_str.rs
//
// This is similar to from_into.rs, but this time we'll implement `FromStr` and
// return errors instead of falling back to a default value. Additionally, upon
// implementing FromStr, you can use the `parse` method on strings to generate
// an object of the implementor type. You can read more about it at
// https://doc.rust-lang.org/std/str/trait.FromStr.html
//
// Execute `rustlings hint from_str` or use the `hint` watch subcommand for a
// hint.
use std::num::ParseIntError;
use std::str::FromStr;
#[derive(Debug, PartialEq)]
struct Person {
name: String,
age: usize,
}
// We will use this error type for the `FromStr` implementation.
#[derive(Debug, PartialEq)]
enum ParsePersonError {
// Empty input string
Empty,
// Incorrect number of fields
BadLen,
// Empty name field
NoName,
// Wrapped error from parse::<usize>()
ParseInt(ParseIntError),
}
// I AM DONE
// Steps:
// 1. If the length of the provided string is 0, an error should be returned
// 2. Split the given string on the commas present in it
// 3. Only 2 elements should be returned from the split, otherwise return an
// error
// 4. Extract the first element from the split operation and use it as the name
// 5. Extract the other element from the split operation and parse it into a
// `usize` as the age with something like `"4".parse::<usize>()`
// 6. If while extracting the name and the age something goes wrong, an error
// should be returned
// If everything goes well, then return a Result of a Person object
//
// As an aside: `Box<dyn Error>` implements `From<&'_ str>`. This means that if
// you want to return a string error message, you can do so via just using
// return `Err("my error message".into())`.
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.len() ==0 {
return Err(ParsePersonError::Empty)
}
let vecData: Vec<&str> = s.split(',').collect();
if vecData.len() !=2 {
return Err(ParsePersonError::BadLen)
}
let name=String::from(vecData[0]);
if name.is_empty() {
return Err(ParsePersonError::NoName)
}
// 如果姓名字符串能转成usize 就赋值给age
let age = match vecData[1].parse::<usize>() {
Ok(age)=>age,
Err(e) => return Err(ParsePersonError::ParseInt(e))
};
Ok(Person {
name,
age
})
}
}
fn main() {
let p = "Mark,20".parse::<Person>().unwrap();
println!("{:?}", p);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_input() {
assert_eq!("".parse::<Person>(), Err(ParsePersonError::Empty));
}
#[test]
fn good_input() {
let p = "John,32".parse::<Person>();
assert!(p.is_ok());
let p = p.unwrap();
assert_eq!(p.name, "John");
assert_eq!(p.age, 32);
}
#[test]
fn missing_age() {
assert!(matches!(
"John,".parse::<Person>(),
Err(ParsePersonError::ParseInt(_))
));
}
#[test]
fn invalid_age() {
assert!(matches!(
"John,twenty".parse::<Person>(),
Err(ParsePersonError::ParseInt(_))
));
}
#[test]
fn missing_comma_and_age() {
assert_eq!("John".parse::<Person>(), Err(ParsePersonError::BadLen));
}
#[test]
fn missing_name() {
assert_eq!(",1".parse::<Person>(), Err(ParsePersonError::NoName));
}
#[test]
fn missing_name_and_age() {
assert!(matches!(
",".parse::<Person>(),
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
));
}
#[test]
fn missing_name_and_invalid_age() {
assert!(matches!(
",one".parse::<Person>(),
Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_))
));
}
#[test]
fn trailing_comma() {
assert_eq!("John,32,".parse::<Person>(), Err(ParsePersonError::BadLen));
}
#[test]
fn trailing_comma_and_some_string() {
assert_eq!(
"John,32,man".parse::<Person>(),
Err(ParsePersonError::BadLen)
);
}
}
88.判断rgb的合法范围
话说没看出来try的用处在哪里
// try_from_into.rs
//
// TryFrom is a simple and safe type conversion that may fail in a controlled
// way under some circumstances. Basically, this is the same as From. The main
// difference is that this should return a Result type instead of the target
// type itself. You can read more about it at
// https://doc.rust-lang.org/std/convert/trait.TryFrom.html
//
// Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for
// a hint.
use std::convert::{TryFrom, TryInto};
#[derive(Debug, PartialEq)]
struct Color {
red: u8,
green: u8,
blue: u8,
}
// We will use this error type for these `TryFrom` conversions.
#[derive(Debug, PartialEq)]
enum IntoColorError {
// Incorrect length of slice
BadLen,
// Integer conversion error
IntConversion,
}
// I AM NOT DONE
// Your task is to complete this implementation and return an Ok result of inner
// type Color. You need to create an implementation for a tuple of three
// integers, an array of three integers, and a slice of integers.
//
// Note that the implementation for tuple and array will be checked at compile
// time, but the slice implementation needs to check the slice length! Also note
// that correct RGB color values must be integers in the 0..=255 range.
// Tuple implementation
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
if tuple.0>255 || tuple.0<0 ||tuple.1>255 || tuple.1<0 ||tuple.2>255 || tuple.2<0 {
return Err(IntoColorError::IntConversion)
}
Ok(Color {
red: tuple.0 as u8,
green: tuple.1 as u8,
blue: tuple.2 as u8,
})
}
}
// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
if arr[0]<0 || arr[0]>255 || arr[1]<0 ||arr[1]>255 || arr[2]<0 ||arr[2]>255 {
return Err(IntoColorError::IntConversion)
}
Ok(Color {
red: arr[0] as u8,
green: arr[1] as u8,
blue: arr[2] as u8,
})
}
}
// Slice implementation
impl TryFrom<&[i16]> for Color {
type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
if slice.len()!=3 {
return Err(IntoColorError::BadLen)
}
if slice[0]<0 || slice[0]>255 ||slice[1]<0 || slice[1]>255 ||slice[2]<0 || slice[2]>255 {
return Err(IntoColorError::IntConversion)
}
Ok(Color {
red: slice[0] as u8,
green: slice[1] as u8,
blue: slice[2] as u8,
})
}
}
fn main() {
// Use the `try_from` function
let c1 = Color::try_from((183, 65, 14));
println!("{:?}", c1);
// Since TryFrom is implemented for Color, we should be able to use TryInto
let c2: Result<Color, _> = [183, 65, 14].try_into();
println!("{:?}", c2);
let v = vec![183, 65, 14];
// With slice we should use `try_from` function
let c3 = Color::try_from(&v[..]);
println!("{:?}", c3);
// or take slice within round brackets and use TryInto
let c4: Result<Color, _> = (&v[..]).try_into();
println!("{:?}", c4);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tuple_out_of_range_positive() {
assert_eq!(
Color::try_from((256, 1000, 10000)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_out_of_range_negative() {
assert_eq!(
Color::try_from((-1, -10, -256)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_sum() {
assert_eq!(
Color::try_from((-1, 255, 255)),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_tuple_correct() {
let c: Result<Color, _> = (183, 65, 14).try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_array_out_of_range_positive() {
let c: Result<Color, _> = [1000, 10000, 256].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_out_of_range_negative() {
let c: Result<Color, _> = [-10, -256, -1].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_sum() {
let c: Result<Color, _> = [-1, 255, 255].try_into();
assert_eq!(c, Err(IntoColorError::IntConversion));
}
#[test]
fn test_array_correct() {
let c: Result<Color, _> = [183, 65, 14].try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_slice_out_of_range_positive() {
let arr = [10000, 256, 1000];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_out_of_range_negative() {
let arr = [-256, -1, -10];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_sum() {
let arr = [-1, 255, 255];
assert_eq!(
Color::try_from(&arr[..]),
Err(IntoColorError::IntConversion)
);
}
#[test]
fn test_slice_correct() {
let v = vec![183, 65, 14];
let c: Result<Color, _> = Color::try_from(&v[..]);
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
fn test_slice_excess_length() {
let v = vec![0, 0, 0, 0];
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
}
#[test]
fn test_slice_insufficient_length() {
let v = vec![0, 0];
assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen));
}
}
89.as_ref与as_mut
as_ref用于将值转为引用
as_mut用于将值转为可变引用
在pow操作的时候需要一个拥有所有权的对象,所以需要调用as_mut方法
差不多是这个意思
// as_ref_mut.rs
//
// AsRef and AsMut allow for cheap reference-to-reference conversions. Read more
// about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html and
// https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
//
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
// Obtain the number of bytes (not characters) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound.
fn byte_counter<T:AsRef<str>>(arg: T) -> usize {
arg.as_ref().as_bytes().len()
}
// Obtain the number of characters (not bytes) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound.
fn char_counter<T:AsRef<str>>(arg: T) -> usize {
arg.as_ref().chars().count()
}
// Squares a number using as_mut().
// TODO: Add the appropriate trait bound.
fn num_sq<T:AsMut<u32>>(arg: &mut T) {
// TODO: Implement the function body.
let availableValue =arg.as_mut();
(*availableValue)=(*availableValue).pow(2)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn different_counts() {
let s = "Café au lait";
assert_ne!(char_counter(s), byte_counter(s));
}
#[test]
fn same_counts() {
let s = "Cafe au lait";
assert_eq!(char_counter(s), byte_counter(s));
}
#[test]
fn different_counts_using_string() {
let s = String::from("Café au lait");
assert_ne!(char_counter(s.clone()), byte_counter(s));
}
#[test]
fn same_counts_using_string() {
let s = String::from("Cafe au lait");
assert_eq!(char_counter(s.clone()), byte_counter(s));
}
#[test]
fn mult_box() {
let mut num: Box<u32> = Box::new(3);
num_sq(&mut num);
assert_eq!(*num, 9);
}
}
90.一个完全蒙蔽的题目
GPT给我的答案
unsafe
关键字告诉编译器,这段代码可能包含不安全的操作,需要开发人员自己来确保其正确性和安全性。
let mut t
:这是一个变量声明,声明了一个名为t
的可变变量。t
的类型是&mut u32
,即一个可变的对u32
类型的引用。
&mut *(address as *mut u32)
:这部分是一个复杂的表达式,用于将address
强制类型转换为*mut u32
,然后进行解引用。具体来说:
address as *mut u32
将address
转换为一个*mut u32
类型的指针。这个指针表示一个指向u32
类型的可变内存地址。&mut *
是解引用操作符,它将指针解引用,以获取指针指向的值。
*t = 0xAABBCCDD
:这是将t
所引用的内存位置设置为0xAABBCCDD
的值。由于t
是可变引用,因此可以通过*t
来修改内存中的值文章来源:https://www.toymoban.com/news/detail-722320.html
// tests5.rs
//
// An `unsafe` in Rust serves as a contract.
//
// When `unsafe` is marked on an item declaration, such as a function,
// a trait or so on, it declares a contract alongside it. However,
// the content of the contract cannot be expressed only by a single keyword.
// Hence, its your responsibility to manually state it in the `# Safety`
// section of your documentation comment on the item.
//
// When `unsafe` is marked on a code block enclosed by curly braces,
// it declares an observance of some contract, such as the validity of some
// pointer parameter, the ownership of some memory address. However, like
// the text above, you still need to state how the contract is observed in
// the comment on the code block.
//
// NOTE: All the comments are for the readability and the maintainability of
// your code, while the Rust compiler hands its trust of soundness of your
// code to yourself! If you cannot prove the memory safety and soundness of
// your own code, take a step back and use safe code instead!
//
// Execute `rustlings hint tests5` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
/// # Safety
///
/// The `address` must contain a mutable reference to a valid `u32` value.
unsafe fn modify_by_address(address: usize) {
// TODO: Fill your safety notice of the code block below to match your
// code's behavior and the contract of this function. You may use the
// comment of the test below as your format reference.
unsafe {
// todo!("Your code goes here")
let mut t = &mut *(&mut *(address as *mut u32) as *mut u32);
*t=0xAABBCCDD
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_success() {
let mut t: u32 = 0x12345678;
// SAFETY: The address is guaranteed to be valid and contains
// a unique reference to a `u32` local variable.
unsafe { modify_by_address(&mut t as *mut u32 as usize) };
assert!(t == 0xAABBCCDD);
}
}
文章来源地址https://www.toymoban.com/news/detail-722320.html
到了这里,关于RustDay06------Exercise[81-90]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!