什么是"名义类型"在固有实施的背景下?

时间:2018-03-14 12:25:01

标签: rust

我目前正在浏览the Rust Documentation以了解内在的实现。什么是"名义类型"当他们说"相关项目与实施类型相关时,他们指的是什么?"?

在C或C ++中是否存在相关模拟?

2 个答案:

答案 0 :(得分:6)

嗯,这是语言参考。学习Rust当然是可能的,但有点像尝试通过阅读字典来学习英语。你试过Rust Book吗?

无论如何,正如第一段所述,“名义类型”是:

impl /* --> */ Point /* <-- this is the "nominal type" */ {
    fn log(&self) { ... }
}

这是固有impl主题的类型。 “可关联项目”是与名义类型相关联的项目(如fnconsttype)。

如果您有段落:

  

我们来谈谈雷蒙德。他的头发是棕色的。他知道如何跳舞。

这大致相当于:

struct Raymond; // introduce the Raymond type.

impl Raymond { // associate some items with Raymond.
    const HAIR: Colour = Colour::Brown;

    fn dance(&mut self) { ... }
}

fn main() {
    let mut ray = Raymond;
    println!("Raymond's hair is {}", Raymond::HAIR);
    ray.dance();
}

(顺便说一下:段落中的代词(如“他”或“他”)将成为self中的Selfimpl

impl正在将这些项目与名义类型相关联。请注意HAIR类型中Raymond的“内部”。您可以 将上述代码编写为:

struct Raymond;

const RAYMOND_HAIR: Colour = Colour::Brown;

fn raymond_dance(ray: &mut Raymond) { ... }

fn main() {
    let mut ray = Raymond;
    println!("Raymond's hair is {}", RAYMOND_HAIR);
    raymond_dance(&mut ray);
}

此处没有固有的impl,因此RAYMOND_HAIRraymond_dance项目不直接与Raymond类型相关联。除了方便之外,两者之间没有根本区别。

至于把它绑回到C ++ ......这很棘手,因为Rust区分了固有和非固有impl和C ++ ...... 。最接近的类比是说它们就像struct体的不是字段的部分,而不是覆盖基类中的方法。

答案 1 :(得分:1)

固有实现相当于使用OOP语言创建类。 Rust的不同之处在于数据与实现分开:

/* Data */
struct Foo {
    // all data there
    //...
}

/* Inherent implementation */
impl Foo {
    fn bar(&self) {
        //...
    }
}
  • 名义类型是您实施的数据。
  • 可关联项是您添加到数据的方法。这些函数很特殊,因为您可以使用语法foo.bar()
  • 调用它们

固有实现的调用方式与 trait implementation 相反:

/* Trait implementation */
impl Debug for Foo {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        //...
    }
}
  • 在固有实现的情况下,该方法仅限于数据。只有这个数据才有意义。
  • 对于特征实现,可以为实现特征的任何数据实现该方法。

C ++中的等价物可以是:

struct Debug {
    virtual std::string fmt() = 0;
}

class Foo: public Debug {
    // all data there
    //...

public:
    /* Equivalent of inherent implementation */
    void bar() {
        //...
    }

    /* Equivalent of trait implementation:
       implementation of base class */
    std::string fmt() {
        //...
    }
}

在C ++中,你不能将“固有实现”与“特征实现”分开(我把它们放在引号之间,因为这些术语在C ++中没有意义,当然)。

请注意,与C ++不同,在Rust中,方法与自由函数并没有太大区别。您可以像这样调用bar方法:

Foo::bar(foo);

如果您定义此功能:

fn qux(f: &Foo) {
    //...
}

它与Foo::bar具有相同的签名。