详解Rust中的方法

目录
  • Rust中的方法
    • 方法的简单概念
    • 定义方法
  • Rust自动引用和解引用
  • 带参数的方法
  • 小结

Rust中的方法

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

方法的简单概念

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

&self 实际上是 self: &Self 的缩写,在一个 impl 块中,Self 类型是 impl 块的类型的别名。方法的第一个参数必须有一个名为 selfSelf 类型的参数,所以 Rust 让你在第一个参数位置上只用 self 这个名字来缩写。传参的时候可以忽略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 的枚举功能,为你的工具箱再添一个工具。

到此这篇关于Rust中的方法的文章就介绍到这了,更多相关Rust中的方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Rust实现grep命令行工具的方法

    目录 一.功能: 二.介绍 2.1 使用到的知识: 2.2 代码 三.使用 一.功能: 1.输入要查询的字符串和文件名,输出所有匹配的行的内容 2.如果设置环境变量IGNORE_CASE,则grep匹配将忽略大小写 3.可使用 > 符号来重定向标准输出到指定文件中 二.介绍 2.1 使用到的知识: 读取命令行参数 读取文件内容 错误处理 Test Driven Development(TDD) 使用环境变量控制不同行为 2.2 代码 1.main.rs use std::env; use std

  • Rust 搭建一个小程序运行环境的方法详解

    目录 从零到一:构建一个能运行小程序的App FinClip 安全沙箱的初始化 获得 SDK Key 以及 SDK Secret 的两种方式 方式一:采用 FinClip.com 托管服务 方式二:自行部署 FinClip 社区版 FinClip SDK 在 App 中的初始化 Rust 开发环境的准备 Rust 代码编译成 iOS 静态库的验证 搭建一个FinClip社区版docker运行环境,安装设置Rust开发编译iOS代码的环境,设置xcode的项目配合,集成FinClip SDK,准备

  • python实现上传样本到virustotal并查询扫描信息的方法

    本文实例讲述了python实现上传样本到virustotal并查询扫描信息的方法.分享给大家供大家参考.具体方法如下: import simplejson import urllib import urllib2 import os MD5 = "5248f774d2ee0a10936d0b1dc89107f1" MD5 = "12fa5fb74201d9b6a14f63fbf9a81ff6" #do not have report on virustotal.co

  • Go调用Rust方法及外部函数接口前置

    前言 近期 Rust 社区/团队有些变动,所以再一次将 Rust 拉到大多数人眼前. 我最近看到很多小伙伴说的话: Rust 还值得学吗?社区是不是不稳定呀 Rust 和 Go 哪个好? Rust 还值得学吗? 这些问题如果有人来问我,那我的回答是: 小孩子才做选择,我都要! 当然,关于 Rust 和 Go 的问题也不算新,比如之前的一条推文: 我在本篇中就来介绍下如何用 Go 调用 Rust. 当然,这篇中我基本上不会去比较 Go 和 Rust 的功能,或者这种方式的性能之类的,Just fo

  • 在Rust web服务中使用Redis的方法

    Redis一直是网络生态系统的重要组成部分,它经常用作缓存.消息代理或简单地用作数据存储. 在这篇文章中,我们将演示如何在一个Rust web应用程序中使用Redis. 我们将探索两种种使用Redis的方法: 使用同步连接池 使用异步连接池 对于同步池,我们使用基于r2d2库的r2d2-redis.我们在异步解决方案中使用mobc,还有许多其他异步连接池,如deadpool和bb8,它们都以类似的方式工作. 话不多说,让我们开始吧! 新建一个项目: cargo new rust-redis-we

  • Rust use关键字妙用及模块内容拆分方法

    目录 前言 1.rust 中的use关键字 1.1.将模块标识符引入当前作用域 1.2.use特点与习惯用法 1.3.使用pub use 重新导出名称 1.4.使用外部包(package)以及标准库 1.5.使用嵌套路径清理大量 use 语句 1.6.通配符 * 2.模块内容拆分 前言 书接上文,本篇补充rust 组织管理中模块的细节知识,比如模块拆分.此外介绍use关键字的习惯用法,快速引用自定义模块内容或标准库,以此优化代码书写. 1.rust 中的use关键字 如果我说use与C/C++中

  • 在PHP程序中使用Rust扩展的方法

     C或PHP中的Rust 我的基本出发点就是写一些可以编译的Rust代码到一个库里面,并写为它一些C的头文件,在C中为被调用的PHP做一个拓展.虽然并不是很简单,但是很有趣. Rust FFI(foreign function interface) 我所做的第一件事情就是摆弄Rust与C连接的Rust的外部函数接口.我曾用简单的方法(hello_from_rust)写过一个灵活的库,伴有单一的声明(a pointer to a C char, otherwise known as a strin

  • 详解Rust中的方法

    目录 Rust中的方法 方法的简单概念 定义方法 Rust自动引用和解引用 带参数的方法 小结 Rust中的方法 方法其实就是结构体的成员函数,在C语言中的结构体是没有成员函数的,但是Rust毕竟也是一门面向对象的编程语言,所以给结构体加上方法的特性很符合面向对象的特点. 方法的简单概念 方法(method)与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码.不过方法与函数是不同的,因为它们在结构体的上下文中被定义,并且它们第一个参数总是

  • 详解Rust中三种循环(loop,while,for)的使用

    目录 楔子 loop 循环 while 循环 for 循环 楔子 我们常常需要重复执行同一段代码,针对这种场景,Rust 提供了多种循环(loop)工具.一个循环会执行循环体中的代码直到结尾,并紧接着回到开头继续执行. 而 Rust 提供了 3 种循环:loop.while 和 for,下面逐一讲解. loop 循环 我们可以使用 loop 关键字来指示 Rust 反复执行某一段代码,直到我们显式地声明退出为止. fn main() {     loop {         println!("

  • 详解Java中native方法的使用

    今天在网上学习时碰到有关于 native修饰符所修饰的方法,上网查了查,觉得很有意思记录一下 1.native简介 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C.这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数. native是与C++联合开发的时候用的!使用nat

  • 详解Python中__new__方法的作用

    目录 前言 一.__new__方法简介 1.初始化数据加载+解析类实例 2.初始化数据加载重写new方法+解析类实例 二.单例模式 1.用new方法如何实现单例模式 2.如何控制类仅执行一次初始化方法 三.多例模式 总结 前言 Python中类的构造方法__new__方法有何作用? Python类中有些方法名.属性名的前后都添加__双下画线,这种方法.属性通常属于Python的特殊方法和特殊属性.通过重写这些方法或直接调用这些方法来实现特殊功能.今天来聊聊构造方法__new__实际程序的应用场景

  • 详解python中init方法和随机数方法

    1.__init__方法的使用 2.random方法的使用 在python中,有一些方法是特殊的,是以两个下划线开始,两个下划线结束,定义类,最常用的方法就是__init__()方法,这是类的初始化方法,类似于C#或Java的构造函数.在创建对象的时候自动执行. class Person(object): ''' 这里定义的属性 为 静态的 ''' empCount = 0 # 创建对象的时候自动执行 def __init__(self, name): print('初始化方法.....') s

  • 详解Android中Drawable方法

    本文为大家分享了Android中Drawable方法的详细使用方法,供大家参考,具体内容如下 1. BitmapDrawable相关方法: 新建在drawable目录下面,示例如下: <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:antialias="true" android:dither="true" android:filter=&

  • 详解Rust中的workspace

    目录 一.目录结构 二.子crata中的Cargo.toml声明 三.代码引用 java项目中用maven管理代码时,如果遇到大型工程,一般会拆分成不同的模块,比如spring-mvc中,通常会按model, view, controller建3个模块,然后根据一定的依赖关系进行引用.这个概念在Rust中是通用的,只不过maven换成了cargo,而模块变成了crate,看下面的例子. 一.目录结构 .├── Cargo.toml├── controller│   ├── Cargo.toml│

  • 详解Ruby中的方法概念

    Ruby方法跟其他编程语言中的函数非常相似, Ruby方法用于捆绑到一个单元中的一个或多个重复的语句. 方法名称应以小写字母开始.如果一个方法的名称以大写字母开始,Ruby可能会认为这是一个常数,因此可以正确解析调用. 方法应该定义Ruby的之前调用他们,否则会引发一个异常未定义的方法调用. 语法: def method_name [( [arg [= default]]...[, * arg [, &expr ]])] expr.. end 所以,可以定义一个简单的方法如下: def meth

  • 详解Python中DOM方法的动态性

    文档对象模型 xml.dom 模块对于 Python 程序员来说,可能是使用 XML 文档时功能最强大的工具.不幸的是,XML-SIG 提供的文档目前来说还比较少.W3C 语言无关的 DOM 规范填补了这方面的部分空白.但 Python 程序员最好有一个特定于 Python 语言的 DOM 的快速入门指南.本文旨在提供这样一个指南.在 上一篇专栏文章 中,某些样本中使用了样本 quotations.dtd 文件,并且这些文件可以与本文中的代码样本档案文件一起使用. 有必要了解 DOM 的确切含义

  • 详解Python中find()方法的使用

    find()方法判断字符串str,如果起始索引beg和结束end索引能找到在字符串或字符串的一个子串中. 语法 以下是find()方法的语法: str.find(str, beg=0 end=len(string)) 参数 str -- 此选项指定要搜索的字符串. beg -- 这是开始索引,默认情况下为 0. end -- 这是结束索引,默认情况下它等于字符串的长度. 返回值 如果找到此方法返回的索引,否则返回-1. 例子 下面的例子显示了find()方法的使用. #!/usr/bin/pyt

随机推荐