struct的方法

128 阅读2分钟

1. struct方法的定义

方法和函数类似

都有

  • fn关键字
  • 名称
  • 参数
  • 返回值

不同之处

  • 方法是在struct(或enum、trait对象)的上下文中定义
  • 第一个参数是self,表示方法被调用的struct实例
struct Rect {
    width: u32,
    length: u32,
}

impl Rect {
    fn area(&self) -> u32 {
        self.width * self.length
    }
}

fn main() {
    let rect = Rect {
        width: 30,
        length: 50,
    };
    println!("{}",rect.area());
}

fn area(rects: &Rect) -> u32 {
    rects.width * rects.length
}

定义方法

  • 在impl块里定义方法
  • 方法的第一个参数可以是&self,也可以获得其所有权可变借用

2.方法调用的运算符

c/c++中:object->something() 和 (*object).something() 一样

然而在rust中没有 -> 运算符

但是rust会自动引用或解引用,在调用方法的时候就会发生这种行为。

在调用方法时,rust根据情况自动添加&、&mut或*,以便object可以匹配方法的签名。

下面两行代码效果相同

p1.distance(&p2);
(&p1).distance(&p2);

方法中可以有多个参数

struct Rect {
    width: u32,
    length: u32,
}

impl Rect {
    fn area(&self) -> u32 {
        self.width * self.length
    }
    fn can_hold(&self, other:&Rect) -> bool {
        self.width > other.width && self.length > other.length
    }
}  

fn main() {
    let rect = Rect {
        width: 30,
        length: 50,
    };

    let rect2 = Rect {
        width: 10,
        length: 40,
    };

    let rect3 = Rect {
        width: 50,
        length: 60,
    };
    println!("{}",rect.area()); // 1500
    println!("{}",rect.can_hold(&rect2)); // true
    println!("{}",rect2.can_hold(&rect3)); // false
}

3.关联函数

可以在impl块里定义不把self作为第一个参数的函数,叫做关联函数,不叫方法。

例如 String::from()

关联函数通常用于构造器

::符号,用于

  • 关联函数
  • 模块创建的命名空间
struct Rect {
    width: u32,
    length: u32,
}

impl Rect {
    fn area(&self) -> u32 {
        self.width * self.length
    }

    // 方法可以有多个参数
    fn can_hold(&self, other:&Rect) -> bool {
        self.width > other.width && self.length > other.length
    }

    // 关联函数
    fn square(size: u32) -> Rect {
        Rect {
            width: size,
            length: size
        }
    }
}

fn main() {
    let rect = Rect {
        width: 30,
        length: 50,
    };
    let rect2 = Rect {
        width: 10,
        length: 40,
    };
    let rect3 = Rect {
        width: 50,
        length: 60,
    };
    
    // 调用关联函数
    let rect4 = Rect::square(10);
    println!("{}",rect.area());
    println!("{}",rect.can_hold(&rect2));
    println!("{}",rect2.can_hold(&rect3));
}

fn area(rects: &Rect) -> u32 {
    rects.width * rects.length
}

4.多个impl

每个struct允许拥有多个impl块