亲宝软件园·资讯

展开

Rust中的方法

Cukor丘克 人气:0

Rust中的方法

方法其实就是结构体的成员函数,在C语言中的结构体是没有成员函数的,但是Rust毕竟也是一门面向对象的编程语言,所以给结构体加上方法的特性很符合面向对象的特点。

方法的简单概念

方法(method)与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义,并且它们第一个参数总是 self,它代表调用该方法的结构体实例。

&self 实际上是 self: &Self 的缩写,在一个 impl 块中,Self 类型是 impl 块的类型的别名。方法的第一个参数必须有一个名为 selfSelf 类型的参数,所以 Rust 让你在第一个参数位置上只用 self 这个名字来缩写。传参的时候可以忽略self的传参。

上面这段话是官方文档对方法的描述。如果学过面向对象的应该理解起来是没人任何问题的,方法就是类中的成员函数,在调用方法是必须通过类的实例对象类调用。

使用方法代替函数的好处:

定义方法

定义方法的方式和定义函数的方式类似,也是采用fn作为标识,但是方法比函数多一点的就是需要被包含在impl中。

impl是implementation的简写,翻译成中文就是实施,实现的意思。在Rust中所有的方法都必须在对应的结构体的impl中实现,并且方法的第一个参数是&self,其中&self就是指向当前对象的引用,类似于C++中的this、Java中的this、Python中的self.

基本结构:

impl 结构体名 {
    方法1...
    方法2...
    ....
    方法n...
}

//也可以再开一个impl
impl 结构体名 {
    方法n+1....
}

//其中以上的效果和下面写法等效
impl 结构体名 {
        方法1...
    方法2...
    ....
    方法n...
    方法n+1....
}

可以重开一个impl的特性就像C++中的namespace一样,如果想了解namespace的可自行查询资料。

综上所述,impl的作用就是用来标识哪些方法是属于哪个结构体的。

例子:

struct MM {
    name: String,
    age: u8,
}

impl MM {
    fn get_name(&self) -> &str {
        &self.name
    }
    fn get_age(&self) -> &u8 {
        &self.age
    }
}

impl MM {
    fn show(&self) {
        println!("name: {}", self.name);
        println!("age: {}", self.age);
    }
}
/*上面两个impl等效于以下代码
impl MM {
    fn get_name(&self) -> &str {
        &self.name
    }
    
    fn get_age(&self) -> &u8 {
        &self.age
    }
    
    fn show(&self) {
        println!("name: {}", self.name);
        println!("age: {}", self.age);
    }
}
*/
fn main() {
    let mm = MM {
        name: String::from("Alice"),
        age: 18,
    };
    mm.show();
    println!("{}的名字叫: {}, 她今年{}岁了", mm.name, mm.get_name(), mm.get_age());
}

结果:

name: Alice
age: 18
Alice的名字叫: Alice, 她今年18岁了

Rust自动引用和解引用

在C++中访问对象的内容,一般都是使用指针和指针运算符->来访问对象中的属性(成员变量)和行为(成员函数)。但是在Rust没有和->等效的运算符。Rust是存在了自动引用和解引用的功能。

当使用对象来调用方法时,Rust会自动为对象添加&&mut*以便对象与方法签名匹配,即下面的代码是等价的:

mm.show();		//这种方法比较简洁
(&mm).show();	//这种方法稍微多了点东西

这种自动引用的行为之所以有效,是因为方法有一个明确的接收者———— self 的类型。在给出接收者方法名的前提下,Rust 可以明确地计算出方法是仅仅读取(&self),做出修改(&mut self)或者是获取所有权(self)。事实上,Rust 对方法接收者的隐式借用让所有权在实践中更友好。

//以下都是等效的,都可以修改age的值
mm.age = 19;
(&mut mm).age = 89;

Rust 对方法接收者的隐式借用让所有权在实践中更友好。意思就是使用对象直接点操作就行了。

带参数的方法

因为方法和函数是类似的,所以在方法中也是可以传参的。

直接看一个例子就直接跳过了。

impl MM {	//前面已经声明过MM的结构体了
    fn eat(&self, food: &String) {
        println!("{}想吃{}", self.name, food);
    }
}
fn main() {
    let mm = MM {
        name: String::from("Alice"),
        age: 18,
        money: 100,
    };
    mm.eat(&"手撕鸡".to_string());
}

结果:

Alice想吃手撕鸡

小结

结构体有意义的自定义类型。通过结构体,我们可以将相关联的数据片段联系起来并命名它们,这样可以使得代码更加清晰。在 impl 块中,你可以定义与你的类型相关联的函数,而方法是一种相关联的函数,让你指定结构体的实例所具有的行为。

但结构体并不是创建自定义类型的唯一方法:让我们转向 Rust 的枚举功能,为你的工具箱再添一个工具。

加载全部内容

相关教程
猜你喜欢
用户评论