模块系统

模块系统

Rust有两个与模块 (module) 系统相关的独特术语:cratemodule, 其中包装箱 (crate) 与其它语言中的 libary 或者 package 作用一样。 每个包装箱都有一个隐藏的根模块,在根模块下可以定义一个子模块树, 其路径采用::作为分隔符。包装箱由条目 (item) 构成,多个条目通过模块组织在一起。

定义模块

使用mod关键字定义我们的模块:

// in src/lib.rs

mod chinese {
    mod greetings {

    }

    mod farewells {

    }
}

mod english {
    mod greetings {

    }

    mod farewells {

    }
}

定义了四个子模块chinese::{greetings, farewells}english::{greetings, farewells}。 模块默认是私有的,可以使用pub关键字将其设置成公开,只有公开的条目才允许在模块外部访问。

实践中更好的组织方式是将一个包装箱分拆到多个文件:

// in src/lib.rs

pub mod chinese;

pub mod english;

这两句声明告诉Rust查看src/chinese.rssrc/english.rs, 或者src/chinese/mod.rssrc/english/mod.rs。 先添加一些函数:

// in src/chinese/greetings.rs

pub fn hello() -> String {
    "你好!".to_string()
}
// in src/chinese/farewells.rs

pub fn goodbye() -> String {
    "再见!".to_string()
}
// in src/english/greetings.rs

pub fn hello() -> String {
    "Hello!".to_string()
}
// in src/english/farewells.rs

pub fn goodbye() -> String {
    "Goodbye!".to_string()
}

函数默认也是私有的,为了后面的使用我们需要pub关键字使其成为公有。

导入 crate

为了使用我们前面创建的名为phrases的包装箱,需要先声明导入

// in src/main.rs

extern crate phrases;

fn main() {
    println!("Hello in Chinese: {}", phrases::chinese::greetings::hello());
}

Rust还有一个use关键字,允许我们导入包装箱中的条目到当前的作用域内:

// in src/main.rs

extern crate phrases;

use phrases::chinese::greetings;
use phrases::chinese::farewells::goodbye;

fn main() {
    println!("Hello in Chinese: {}", greetings::hello());
    println!("Goodbye in Chinese: {}", goodbye());
}

但是,我们不推荐直接导入函数,这样更容易导致命名空间冲突,只导入模块是更好的做法。 如果要导入来自同一模块的多个条目,可以使用大括号简写:

use phrases::chinese::{greetings, farewells};

如果是导入全部,可以使用通配符*。重命名可以使用as关键字:

use phrases::chinese::greetings as chinese_greetings;

有时我们需要将外部包装箱里面的函数导入到另一个模块内, 这时可以使用pub use来提供扩展接口而不映射代码层级结构。 比如

// in src/english/mod.rs

pub use self::greetings::hello;
pub use self::farewells::goodbye;

mod greetings;

mod farewells;

其中pub use声明将函数带入了当前模块中, 使得我们现在有了phrases::english::hello()函数和phrases::english::goodbye()函数, 即使它们的定义位于phrases::english::greetings::hello()phrases::english::farewells::goodbye()中, 内部代码的组织结构不能反映我们的扩展接口。

默认情况下,use声明表示从根包装箱开始的绝对路径。 此外,我们可以使用use self::表示相对于当前模块的位置, use super::表示当前位置的上一级,以::为前缀的路径表示根包装箱路径。

属性

在Rust中,属性 (attribute) 是应用于包装箱、模块或者条目的元数据 (metadata), 主要用于:

  • 实现条件编译 (conditional compilation)
  • 设置包装箱名字、版本以及类型
  • 取消可疑代码的警告
  • 设置编译器选项
  • 链接外部库
  • 标记测试函数

属性有两种语法:#![crate_attribute]应用于整个包装箱, 而#[crate_attribute]应用于紧邻的一个模块或者条目。 属性的参数也有三种不同的形式:

  • #[attribute = "value"]
  • #[attribute(key = "value")]
  • #[attribute(value)]

下面列举几个经常用到的属性:

  • #[path="foo.rs"]用于设置一个模块需要载入的文件路径。
  • #[allow(dead_code)]用于取消对死代码的默认lint检查。
  • #[derive(PartialEq, Clone)]用于自动推导PartialEqClone这两个特性的实现。
use foo::baz::foobaz; // foo is at the root of the crate

mod foo {
    use foo::bar::foobar; // foo is at crate root
    use self::baz::foobaz; // self refers to module ‘foo‘

    pub mod bar {
        pub fn foobar() { }
    }

    pub mod baz {
        use super::bar::foobar; // super refers to module ‘foo‘
        pub fn foobaz() { }
    }
}
时间: 2024-08-04 20:05:42

模块系统的相关文章

【node.js】模块系统、函数

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统. 一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 创建模块 在 Node.js 中,创建一个模块非常简单,如下我们创建一个 'hello.js' 文件,代码如下: var hello = require('./hello'); hello.world(); 以上实例中,代码 require('./hello') 引入了当前目录下的hello.

nodeJS基础:模块系统

1. node JS 模块介绍 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的.换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 2. 创建模块 Node.js 提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的

NodeJS模块系统

为了让NodeJS的文件可以相互调用,NodeJS提供了一个简单的模块系统. 模块是NodeJS应用程序的基本组成部分,文件和模块是一一对应的,换言之,一个NodeJS文件就是一个模块,这个文件可能是javascript代码,JSON或者编译过的C/C++扩展. 创建模块 // hello.js exports.world = function(){ console.log('hello world'); } // main.js var hello = require('./hello');

Node.js 的模块系统

Node.js的模块系统是借鉴 CommonJS 的 Modules 规范实现的,因此,下面我们需要先了解 CommonJS 的 Modules 规范,希望对大家学习Node.js有所帮助. CommonJS 的 Modules 规范 CommonJS 对模块的定义非常简单,主要分为 模块引用.模块定义和模块标识三个部分. 1. 模块引用 - require() 方法 2. 模块定义 - module.exports 对象 3. 模块标识 - 传递给 require() 方法的参数 通过 Com

初学Node(三)模块系统

模块系统 Node根据CommonJS规范实现了一套自己的模块机制,可以使用require()导入一个模块,使用module.exports导出一个模块. require使用 在Node中我们可以使用require()导入一个模块,此时我们就会获得一个被导入模块的对象,我们就可以利用这个对象来完成一些操作,例如: var fs = require("fs"); fs.readFile("content.txt",function(err,data){ if(err)

ES6 的模块系统

此文为翻译,原文地址在这儿:https://hacks.mozilla.org/2015/08/es6-in-depth-modules/[转] ES6 是 ECMAScript 第 6 版本的简称,这是新一代的 JavaScript 的标准.ES6 in Depth 是关于 ES6 的一系列新特性的介绍. 遥想 2007 年,笔者开始在 Mozilla 的 JavaScript 团队工作的时候,那个时候典型的 JavaScript 程序只有一行代码. 两年之后, Google Map 被发布.

OSGi是什么:Java语言的动态模块系统(一)

OSGi是什么 OSGi亦称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构.OSGi容器已有多家开源实现,比如Knoflerfish.Equinox和Apache的Felix.您可以通过这些容器,把您的应用程序劈分为多个模块单元,这样,您就可以更容易地管理这些模块单元之间的交叉依赖关系. OSGi规范和Servlet规范及EJB规范类似,该规范定义了两种对象,一是容器对外提供的服务对象,另一个是容器和您的应用程序之间必须遵守的契约,其中,服务对象是容器要实现的.您如果想要在

Node,js的模块系统

模块系统 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的.换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 创建模块 在 Node.js 中,创建一个模块非常简单,如下我们创建一个 'mk.js' 文件,代码如下: 以上实例中,代码 require('./hello') 引入了当前目录下的hello.js文件(.

nodejs的模块系统(实例分析exprots和module.exprots)

前言:工欲善其事,必先利其器.模块系统是nodejs组织管理代码的利器也是调用第三方代码的途径,本文将详细讲解nodejs的模块系统.在文章最后实例分析一下exprots和module.exprots. nodejs的模块 什么是模块? node.js通过实现CommonJS的Modules/1.0标准引入了模块(module)概念,模块是Node.js的基本组成部分.一个node.js文件就是一个模块,也就是说文件和模块是一一对应的关系.这个文件可以是JavaScript代码,JSON或者编译

<<ABP文档 - 框架>> 1.3 模块系统

文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依赖 插件模块 Asp.net Core Asp.net Mvc,Web Api 插件中的控制器 附加程序集 自定义模块方法 模块配置 模块生命期 简介 ABP为创建模块及组织它们提供基础框架.一个模块可依赖于另一个模块.通常地,一个程序集做为一个模块.如果你的应用是多个程序集,建议为每个程序集定义一