
Rust Study Day7
本文最后更新于 2024-03-14,本文发布时间距今超过 90 天, 文章内容可能已经过时。最新内容请以官方内容为准
Rust Study Day7
1. Trait Study
using trait to limit the variable type
fn add<T: std::ops::Add<Output = T>>(a:T, b:T) -> T {
a + b
}
using trait as the input parameters to limit the parameter type
pub fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
- trait bound
- Multi-trait
- Where
fn trait_dyn(){
let birds = vec![<dyn Bird>::new(Duck),<dyn Bird>::new(Swan)];
for bird in birds {
bird.quack();
// 当 duck 和 swan 变成 bird 后,它们都忘了如何翱翔于天际,只记得该怎么叫唤了。。
// 因此,以下代码会报错
// bird.fly();
}
}
fn calculate_length(s: &String) -> usize {
s.len()
}
// Studying mods
// **************
// 1. generics
pub mod generics {
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
pub fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
pub fn point_mixup() {
let p1 = Point { x: 5, y: 10.4 };
let p2 = Point { x: "Hello", y: 'c' };
let p3 = p1.mixup(p2);
println!("p3.x = {:?}, p3.y = {:?}", p3.x, p3.y);
}
}
// 2. trait
pub mod traitsstudy{
pub trait Bird {
fn quack(&self);
}
impl dyn Bird{
pub fn new(tp:impl Bird + 'static)->Box<dyn Bird>{
Box::new(tp)
}
}
pub struct Duck;
impl Duck {
fn fly(&self) {
println!("Look, the duck is flying")
}
}
pub struct Swan;
impl Swan {
fn fly(&self) {
println!("Look, the duck.. oh sorry, the swan is flying")
}
}
impl Bird for Duck {
fn quack(&self) {
println!("{}", "duck duck");
}
}
impl Bird for Swan {
fn quack(&self) {
println!("{}", "swan swan");
}
}
}
return a impl [trait] type
fn new_duck() -> impl Bird {
Duck
}
attributes
using attributes to derive traits or mark target
- using derive to impl traits
#[derive(Debug)] // derive Debug to make it support {:?}. So, it can be printed now.
struct Point{
x: i32,
y: i32
}
fn main() {
let p = Point{x:3,y:3};
println!("{:?}",p);
}
common derive traits
- Debug: Enables printing targets with
{:?}
, providing a structured debug output. - PartialEq: Allows targets to perform equality checks (
==
and!=
). - PartialOrd: Enables targets to perform ordering comparisons (
<
,<=
,>=
,>
).
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self {
x,
y,
}
}
}
impl<T: std::fmt::Debug + PartialOrd> Pair<T> {
fn cmp_display(&self) {
if self.x >= self.y {
println!("The largest member is x = {:?}", self.x);
} else {
println!("The largest member is y = {:?}", self.y);
}
}
}
#[derive(Debug, PartialEq, PartialOrd)]
struct Unit(i32);
fn main() {
let pair = Pair{
x: Unit(1),
y: Unit(3)
};
pair.cmp_display();
}
using std::fmt::Display
trait to format our output string
// Body defination ingored...
#[derive(Debug,PartialEq, PartialOrd)]
pub enum AnimalType{
Terrestrial(Body),
Amphibians(Body),
Marine(Body)
}
impl std::fmt::Display for AnimalType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Terrestrial(_) => write!(f, "Terrestrial"),
Self::Amphibians(_) => write!(f, "Amphibians"),
Self::Marine(_) => write!(f, "Marine"),
}
}
}
more about traits and generics
pub mod traitfeatures{
#[derive(Debug,PartialEq, PartialOrd)]
pub struct Body{ legs:u8, hands:u8, eyes:u8}
#[derive(Debug,PartialEq, PartialOrd)]
pub enum AnimalType{
Terrestrial(Body),
Amphibians(Body),
Marine(Body)
}
impl std::fmt::Display for AnimalType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Terrestrial(_) => write!(f, "Terrestrial"),
Self::Amphibians(_) => write!(f, "Amphibians"),
Self::Marine(_) => write!(f, "Marine"),
}
}
}
#[derive(Debug)]
pub struct Animals{
name:String,
animal_type:AnimalType
}
impl Animals {
// Bound methods
pub fn new(name:&str,animal_type:AnimalType) -> Animals{
Animals{
name:name.to_string(),
animal_type,
}
}
// Functions
pub fn name(&self)->&str{
self.name.as_str()
}
pub fn animal_type(&self)-> &AnimalType {
&self.animal_type
}
}
pub mod traitimpl{
use super::{AnimalType, Animals};
pub(crate) trait IActions {
fn name(&self) -> String;
fn r#type(&self) ->String;
fn forward(&self,steps:u8);
fn eat(&self,weight_kg:u16){
println!("{}-{} ate {} kilogram.",self.r#type(),self.name(),weight_kg);
}
}
pub trait Icognization {
fn has_large_brain(&self)->bool;
fn can_follow_command(&self)->u8{
if self.has_large_brain() {1} else {0}
}
}
impl IActions for Animals {
fn forward(&self,steps:u8) {
print!("{:?}-{} forward {}",self.animal_type,self.name,steps);
}
fn name(&self) -> String {
self.name().to_string()
}
fn r#type(&self) -> String {
self.animal_type.to_string()
}
}
impl Icognization for Animals {
fn has_large_brain(&self)->bool {
match self.animal_type {
AnimalType::Terrestrial(_)=>false,
_=> true
}
}
}
// using trait parameter to limit
fn is_intelligence_trait_para(species: &impl Icognization) -> bool {
if species.can_follow_command() == 1 {
true
}else {
false
}
}
// trait bound
fn is_intelligence<T:Icognization>(species: &T) -> bool {
if species.can_follow_command() == 1 {
true
}else {
false
}
}
// using where to limit the T
fn does_large_brain_need_more_energy<T>(species: &T) -> bool
where T: Icognization + IActions
{
let eat_large = species.name().contains("Terrestrial");
eat_large && species.has_large_brain()
}
}
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Unic
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果