具有泛型的特质中的 self 是什么?

问题描述 投票:0回答:3

目标:为任何具有

to_string()
的类型实现特征的默认实现。

所以我的方法实际上可能是完全错误的。但我首先以这种方式问这个问题,因为它仍然是一个有趣的问题。

use core::fmt::Display

trait MyStyle<T: Display> {
  fn pretty(&self) -> String {
     let buf = self.to_string();
     // manipulate buf
     buf
  }
}

上面的代码中,

self
到底是什么?我的环境(通过
rust-analyzer
)只是告诉我
self: &Self // size = 8, align = 0x8
。但它是什么类型?

显然这段代码不起作用,否则我就不会在这里,因为我明白了

方法

to_string
存在供参考
&Self
,但不满足其特征界限。

如果它说

to_string
存在,则表明
self
可能是对
Display
的一些引用,但我不明白其余部分,以及为什么它无法编译。

rust traits
3个回答
2
投票
特征中的

Self
指的是实现该特征的类型。因此,在特征定义中,它代表实现该特征的any类型。您可以将其视为通用的
S
,其中
S: MyTrait<T>
。它并不指一种单一类型。

目标:为任何具有 to_string() 的类型实现特征的默认实现。

这非常简单,通过使你的特质变得通用,你可能会遇到过于复杂的事情。这可能就是您想要的:

use std::fmt::Display;

trait MyStyle: Display {
    fn pretty(&self) -> String {
        let buf = self.to_string();
        // manipulate buf
        buf
    }
}

可能需要额外的

impl<T> MyStyle for T where T: Display {}
来为任何实现
Display
的内容创建一个全面的实现。


2
投票

在特征实现中,

&self
基本上是
self: &Self
的语法糖,
Self
是实现该特征的实际类型的占位符类型。这在定义类似构造函数的关联方法的特征中尤其明显,例如
Default
特征
,本质上是:

trait Default {
    fn default() -> Self;
}

struct A {};
impl Default for A {
    fn default() -> A { // NOTE: Self == A here
        A {}
    }
}

请注意,在通用特征上添加特征边界是相当严格的。更惯用的做法是使特征完全通用,然后定义一个全面的实现。例如

trait MyStyle {
     fn pretty(&self) -> String;
}

impl<T> MyStyle for T where T: Display {
    fn pretty(&self) -> String {
        let buf = format!("-~<[{}]>~-", self);
        buf
    }
}


fn main() {
    println!("{}", 123.pretty());
}

打印:

-~<[123]>~-

现场演示


1
投票

方法

to_string
存在供参考
&Self
,但不满足其特征界限 不满足以下特征界限:
Self: std::fmt::Display

措辞有点混乱。编译器不是说方法

to_string()
存在于for
&Self
。这就是说方法
to_string()
存在,句号。名称
to_string()
指的是实际方法。

例如,如果您改为调用

self.foo_bar_baz()
(该名称不存在)。

let buf = self.foo_bar_baz();

然后编译器会说:

在当前范围内未找到名为

foo_bar_baz
的方法供参考
&Self
&Self

中找不到方法

因为名为

foo_bar_baz
的方法不存在。所以这只是说
to_string()
存在。并不是说它专门为
&Self
而存在。


另外,编译器表示

to_string()
存在。然而,特征边界
Self: std::fmt::Display
并未得到满足。所以不可能给
.to_string()
打电话
&Self

© www.soinside.com 2019 - 2024. All rights reserved.