10-结构体方法

2022/4/29 23:18:52

本文主要是介绍10-结构体方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

方法语法

方法:完成特定功能的代码块(和函数是不同的结构,方法在结构体中定义)

  • 方法与函数类似,使用 fn 关键字名称声明,可以拥有参数返回值,同时包含在某处调用该方法时会执行的代码

  • 与函数不同之处

    • 它们在结构体(或者枚举或 trait 对象)的上下文中被定义

    • 第一个参数是 self,表示方法被调用的结构体实例

定义方法的语法

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {            //impl块中的所有内容都将与 Rectangle 类型相关联
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
}
  • impl块里定义方法(implimplementation 的缩写)
  • 方法的第一个参数可以是&self,也可以获得其所有权self或可变借用&mut self

可以选择将方法的名称与结构中的一个字段相同

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn width(&self) -> bool {    //如果实例的 width 字段的值大于 0,返回 true  
        self.width > 0           //如果该值为 0,则返回 false
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };                           //Rust可以自动识别为字段还是方法
    if rect1.width() {           //在main中,当在 rect1.width 后面加上括号时。Rust 知道指的是方法 width。
                                 //当我们不使用圆括号时,Rust 知道我们指的是字段 width。
        println!("The rectangle has a nonzero width; it is {}", rect1.width);
    }
}

方法的名称与字段同名的方法将被定义为只返回字段中的值,不进行其他操作。这样的方法被称为 gettersRust 并不像其他一些语言那样为结构字段自动实现它们 (?

getters 可以把字段变成私有的,但方法是公共的,这样就可以把对字段的只读访问作为该类型公共 API 的一部分

方法调用的运算符

  • 在C/C++语言中有两个不同的运算符来调用方法:

    • object->something() -> 在一个对象的指针上调用方法
    • (*object).something() . 在对象上调用方法;将object看作指向对象的指针 (*object)就是指针的解引用,即对象
  • Rust没有-> 运算符,但是Rust 有 自动引用和解引用automatic referencing and dereferencing)的功能

    • 当使用 object.something() 调用方法时,Rust 会自动为 object 添加 &&mut* 以便使 object 与方法签名匹配

      p1.distance(&p2);
      (&p1).distance(&p2);      //该两种方法等价
      

方法参数

方法可以有多个参数

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
    fn can_hold(&self, other: &Rectangle) -> bool {     //看长方形是否可以包含另一个长方形                                                 //这个方法有两个参数
        self.width > other.width && self.height > other.height
    }                                                   
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
    let rect2 = Rectangle {
        width: 10,
        height: 40,
    };
    let rect3 = Rectangle {
        width: 60,
        height: 45,
    };
    println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2));
    println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3));
}

关联函数

  • 可以在impl块内定义不把self作为第一个参数的函数,叫做关联函数(不是方法)

    • 例如String::from()
  • 关联函数经常被用作返回一个结构体新实例的构造函数(构造器)

    impl Rectangle {
        fn square(size: u32) -> Rectangle {   //参数为size: u32
            Rectangle {                       //返回的是一个结构体实例
                width: size,
                height: size,
            }
        }
    }
    

    调运时,使用结构体名和 :: 语法

    let sq = Rectangle::square(3);
    

    这个方法位于结构体的命名空间中, :: 语法用于关联函数和模块创建的命名空间

多个impl块

每个结构体都允许拥有多个 impl

可以将一个impl块分为多个

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}


这篇关于10-结构体方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程