坏蛋Dan
知乎@坏蛋Dan
发布时间:2024.1.3

前言

昨天我们用一个小栗子对struct加深了印象,今天我们继续往下学。

坏蛋Dan:rust基础学习--day10


方法语法(Method Syntax)

这标题怪怪的。。。

方法methods和函数functions的用法一样,都是fn关键字声明。

而他俩的不同点则是methods需要被定义在struct、enum(枚举)、trait object中。

methods的第一个参数一定是self,这个self指向调用这个方法的struct实例上下文,相当于js中的this

定义一个method

还记得我们昨天写的栗子吗?我们最后声明了一个Rectstruct,将widthheight关联到rect矩形上,然后我们又写了一个rect的方法用来计算面积area

但其实矩形的面积以及矩形的面积计算方法都是和矩形有关的,所以把矩形的面积以及计算面积的方法放到struct上。

我们先来看下代码

可以看到,定义method的关键字是impl,不过不是写在method前面的,而是给struct的,毕竟这是一个struct里的method

同时在调用方法时不用再传入参数widthheight了,因为这俩属性是他自己的,可以再self(this)上面直接拿到。

有一点你应该注意到了,那就是&self,而不是self: &Rect,这是一种语法糖写法。对于methods来说定义self类型是没必要的,它本身就被定义在struct中,调用它的自然得是它的instance,类型早就固定下来了。当然,你也可以写上。

area属性我们是在获取area方法返回的值之后再赋的值,这样可以,不过还有另外一种方式,可以将area属性放到area这个method里面去赋值。

不过就代码可读性来说会差一些,毕竟赋值是在method中。

另外还有个点说下,那就是属性和方法名是可以一样的,比如:

我们声明了一个width的方法,返回是否有width的判断结果。


关于rust中用点表示法调用方法

C/C++中,调用一个方法有两种方式:

  1. 也是点表示法调用方法,但是只能是用在对象本身的调用上;
  2. 如果是顺着指针调用方法,那么就得用->来调用,比如:object_pointer -> get_data().类似(*object_pointer).get_data()解引用。

但是在rust中就没这个必要, rust会判断当前情况来自动加上&引用或者解引用(dereference)。 比如:

它俩是一样的。

如果还是不明白的话,我们来看下我们的例子

我们并没有用&rect.area(),但实际上并没报错。


关联函数(associated functions)

struct这玩意儿长得像一个类,那么一个类怎么能少了构造函数呢?rust中这种类似构造函数的东西叫做关联函数,它们同样定义在struct中,但是它们的第一个参数并不是实例上下文self,这也就说明struct的实例并不能用点表示法调用这些方法。

另外它们的调用方法是用::

最常见的就是我们的String::fromString::new了,他们都会返回一个字符串实例。而这些字符串实例并不能再.new这样调用。

我们来看个例子

Rect::create就是一个典型的关联函数,它返回一个Rect类型的实例, 可以看到create方法它返回的是一个实例并且他的第一个参数并不是self

另外还可以这样写

最后说一下impl允许同时存在多个,你可以把一整块impl作用域拆分为好几块,这样可阅读性会更强(前提是代码量巨大)


总结

今天我们学了如何定义一个method以及定义associated functions构造函数。

如果觉得对你有用的话,麻烦点个赞,谢谢~

参考

  1. ^rust-method-syntax https://doc.rust-lang.org/book/ch05-03-method-syntax.html#method-syntax
  2. ^rust-define-method https://doc.rust-lang.org/book/ch05-03-method-syntax.html#defining-methods
  3. ^rust-associated-functions https://doc.rust-lang.org/book/ch05-03-method-syntax.html#associated-functions

发布于 2022-12-06 21:38・IP 属地广东