六. 程序项
句法:
Item:
OuterAttribute*
VisItem
| MacroItemVisItem:
Visibility?
(
Module
| ExternCrate
| UseDeclaration
| Function
| TypeAlias
| Struct
| Enumeration
| Union
| ConstantItem
| StaticItem
| Trait
| Implementation
| ExternBlock
)MacroItem:
MacroInvocationSemi
| MacroRulesDefinition
6.1 VisItem(程序项)
程序项在编译时就完全确定下来了,通常在执行期间保持结构稳定,并可以驻留在只读内存中。
有以下几类程序项:
6.1.1 Module (模块)
句法:
Module :
unsafe
?mod
IDENTIFIER;
|unsafe
?mod
IDENTIFIER{
InnerAttribute*
Item*
}
#![allow(unused)]
fn main() {
mod math {
type Complex = (f64, f64);
fn sin(f: f64) -> f64 {
/* ... */
unimplemented!();
}
fn cos(f: f64) -> f64 {
/* ... */
unimplemented!();
}
fn tan(f: f64) -> f64 {
/* ... */
unimplemented!();
}
}
}
模块路径 | 文件系统路径 | 文件内容 |
---|---|---|
crate | lib.rs | mod util; |
crate::util | util.rs | mod config; |
crate::util::config | util/config.rs |
path 属性
#[path = "foo.rs"]
mod c;
Source File | c 's File Location | c 's Module Path |
---|---|---|
src/a/b.rs | src/a/foo.rs | crate::a::b::c |
src/a/mod.rs | src/a/foo.rs | crate::a::c |
mod inline {
#[path = "other.rs"]
mod inner;
}
Source File | inner 's File Location | inner 's Module Path |
---|---|---|
src/a/b.rs | src/a/b/inline/other.rs | crate::a::b::inline::inner |
src/a/mod.rs | src/a/inline/other.rs | crate::a::inline::inner |
模块上的属性
模块和所有程序项一样能接受外部属性。它们也能接受内部属性:可以在带有代码体的模块的 {
之后,也可以在模块源文件的开头(但须在可选的 BOM 和 shebang 之后)。
在模块中有意义的内置属性是 cfg、deprecated、doc、lint检查类属性、path 和 no_implicit_prelude。模块也能接受宏属性。
6.1.2 外部crate 声明(ExternCrate)
句法:
ExternCrate :
extern
crate
CrateRef AsClause?;
CrateRef :
IDENTIFIER |self
AsClause :
as
( IDENTIFIER |_
)
外部crate(extern crate
)声明指定了对外部 crate 的依赖关系
extern crate pcre;
extern crate std; // 等同于: extern crate std as std;
extern crate std as ruststd; // 使用其他名字去链接 'std'
当给 Rust crate 命名时,不允许使用连字符(-
)。然而 Cargo 包却可以使用它们。在这种情况下,当 Cargo.toml
文件中没有指定 crate 名称时, Cargo 将透明地将 -
替换为 _
以供 Rust 源文件内的外部crate(extern crate
)声明引用 (详见 RFC 940)。
// 导入 Cargo 包 hello-world
extern crate hello_world; // 连字符被替换为下划线
no_link 属性
可以在外部项(extern crate
item)上指定使用 no_link
属性,以防止此 crate 被链接到编译输出中。这通常用于加载一个 crate 而只访问它的宏。
6.1.3 use 声明(useDeclaration)
句法:
UseDeclaration :
use
UseTree;
UseTree :
(SimplePath?::
)?*
| (SimplePath?::
)?{
(UseTree (,
UseTree )*,
?)?}
| SimplePath (as
( IDENTIFIER |_
) )?
use std::option::Option::{Some, None};
use std::collections::hash_map::{self, HashMap};
fn foo<T>(_: T){}
fn bar(map1: HashMap<String, usize>, map2: hash_map::HashMap<String, usize>){}
fn main() {
// 等价于 'foo(vec![std::option::Option::Some(1.0f64), std::option::Option::None]);'
foo(vec![Some(1.0f64), None]);
// `hash_map` 和 `HashMap` 在当前作用域内都有效.
let map1 = HashMap::new();
let map2 = hash_map::HashMap::new();
bar(map1, map2);
}
use 可见性
mod quux {
pub use self::foo::{bar, baz};
pub mod foo {
pub fn bar() {}
pub fn baz() {}
}
}
fn main() {
quux::bar();
quux::baz();
}
_导入
mod foo {
pub trait Zoo {
fn zoo(&self) {}
}
impl<T> Zoo for T {}
}
use self::foo::Zoo as _;
struct Zoo; // 下划线形式的导入就是为了避免和这个程序项在名字上起冲突
fn main() {
let z = Zoo;
z.zoo();
}
6.1.4 函数(Function)
句法
Function :
FunctionQualifiersfn
IDENTIFIER GenericParams?
(
FunctionParameters?)
FunctionReturnType? WhereClause?
( BlockExpression |;
)FunctionQualifiers :
const
?async
1?unsafe
? (extern
Abi?)?Abi :
STRING_LITERAL | RAW_STRING_LITERALFunctionParameters :
SelfParam,
?
| (SelfParam,
)? FunctionParam (,
FunctionParam)*,
?SelfParam :
OuterAttribute* ( ShorthandSelf | TypedSelf )ShorthandSelf :
(&
|&
Lifetime)?mut
?self
TypedSelf :
mut
?self
:
TypeFunctionParam :
OuterAttribute* ( FunctionParamPattern |...
| Type 2 )FunctionParamPattern :
PatternNoTopAlt:
( Type |...
)FunctionReturnType :
->
Type1
限定符
async
不能在 2015版中使用。2
在2015版中,只有类型的函数参数只允许出现在trait项的关联函数中。
6.1.5 类型别名(typeAlias)
句法
TypeAlias :
type
IDENTIFIER GenericParams? WhereClause? (=
Type )?;
761ad774fcb300f2b506fed7b4dbe753cda88d80 类型别名为现有的类型定义一个新名称。类型别名用关键字type
声明。每个值都是一个唯一的特定的类型,但是可以实现几个不同的 trait,或者兼容几个不同的类型约束
6.1.6 结构体(struct)
句法
Struct :
StructStruct
| TupleStructStructStruct :
struct
IDENTIFIER GenericParams? WhereClause? ({
StructFields?}
|;
)TupleStruct :
struct
IDENTIFIER GenericParams?(
TupleFields?)
WhereClause?;
StructFields :
StructField (,
StructField)*,
?StructField :
OuterAttribute*
Visibility?
IDENTIFIER:
TypeTupleFields :
TupleField (,
TupleField)*,
?TupleField :
OuterAttribute*
Visibility?
Type
6.1.7 枚举(Enumeration)
句法
Enumeration :
enum
IDENTIFIER GenericParams? WhereClause?{
EnumItems?}
EnumItems :
EnumItem (,
EnumItem )*,
?EnumItem :
OuterAttribute* Visibility?
IDENTIFIER ( EnumItemTuple | EnumItemStruct | EnumItemDiscriminant )?EnumItemTuple :
(
TupleFields?)
EnumItemStruct :
{
StructFields?}
EnumItemDiscriminant :
=
Expression
6.1.7 联合体(unique)
句法
Union :
union
IDENTIFIER GenericParams? WhereClause?{
StructFields}
6.1.8 常量(ConstantItem)
句法
ConstantItem :
const
( IDENTIFIER |_
):
Type (=
Expression )?;
6.1.9 静态(StaticItem )
句法
StaticItem :
static
mut
? IDENTIFIER:
Type (=
Expression )?;
静态项类似于常量项,除了它在程序中表示一个精确的内存位置。所有对静态项的引用都指向相同的内存位置。静态项拥有 'static
生存期,它比 Rust 程序中的所有其他生存期都要长。静态项不会在程序结束时调用析构动作 drop。
- 静态项的数据类型必须有
Sync
trait约束,这样才可以让线程安全地访问。 - 常量项不能引用静态项。
应该使用常量项还是应该使用静态项可能会令人困惑。一般来说,常量项应优先于静态项,除非以下情况之一成立:
- 存储大量数据
- 需要静态项的存储地址不变的特性。
- 需要内部可变性。
6.1.10 trait
句法
Trait :
unsafe
?trait
IDENTIFIER GenericParams? (:
TypeParamBounds? )? WhereClause?{
InnerAttribute*
AssociatedItem*
}
#![allow(unused)]
fn main() {
// 有定义和没有定义的相关联trait项的例子
trait Example {
const CONST_NO_DEFAULT: i32;
const CONST_WITH_DEFAULT: i32 = 99;
type TypeNoDefault;
fn method_without_default(&self);
fn method_with_default(&self) {}
}
}
6.1.11 Implementation
句法
Implementation :
InherentImpl | TraitImplInherentImpl :
impl
GenericParams? Type WhereClause?{
InnerAttribute*
AssociatedItem*
}
TraitImpl :
unsafe
?impl
GenericParams?!
? TypePathfor
Type
WhereClause?
{
InnerAttribute*
AssociatedItem*
}
6.1.12 ExternBolck
句法
ExternBlock :
unsafe
?extern
Abi?{
InnerAttribute*
ExternalItem*
}
ExternalItem :
OuterAttribute* (
MacroInvocationSemi
| ( Visibility? ( StaticItem | Function ) )
)
6.1.13 GenericParams
句法
GenericParams :
<
>
|<
(GenericParam,
)* GenericParam,
?>
GenericParam :
[OuterAttribute]* ( LifetimeParam | TypeParam | ConstParam )LifetimeParam :
[LIFETIME_OR_LABEL] (:
[LifetimeBounds] )?TypeParam :
[IDENTIFIER](:
[TypeParamBounds]? )? (=
[Type] )?ConstParam:
const
[IDENTIFIER]:
[Type]
6.1.14 关联项
句法
AssociatedItem :
OuterAttribute* (
MacroInvocationSemi
| ( Visibility? ( TypeAlias | ConstantItem | Function ) )
)