Rust入门失败之Crates&Modules

Cargo

  • Rust 的库默认是.rlib格式, 这个是Rust自身的库类型.默认会将.rlib静态链接到可执行文件项目(bin)

  • 如果需要编译.so.dylib, 在Cargo.toml里增加下面的属性:

    1
    2
    3
    [lib]
    name = "..."
    crate-type = ["dylib"] # could be `staticlib` as well

    The available options are dylib, rlib, staticlib, cdylib, and proc-macro.

Modules

  • Module是Rust的名称空间
  • 每个module初始是空白状态(blank slate), 除了下面的例外被默认被隐含声明
    • extern crate std;
    • use std::prelude::v1::*;
  • 通常会声明一个子模块prelude, 让用户去引用: use xxxx::prelude::*;
  • crate是project层面的代码复用, 而module是一个project内的代码组织
  • Rust不会单独编译某个模块Module, 每次编译一个crate, 会编译它所有的模块
  • use super::xxx子模块引用父级模块, 和unix目录里的 ../类似
  • user self::xxx父模块引用子模块, 和unix目录里的 ./类似
  • extern crate xxx;类似挂载其它crate的根目录到当前项目中
  • 子模块可以引用父模块的私有成员, 但必须逐一列出引用的名称
  • 子模块可以用super::*;直接引用父模块所有pub成员

Pub

  • impl块不能被声明为pub, 而它内部的方法可以
  • 私有的方法methods和字段fields只能在它们被声明的模块使用
  • 可以用pub修饰use, 避免外部用户的长串引用

Attributes

  • #[allow(...)] 例如允许一些警告
  • #[cfg] 设置一些属性, 例如:
    • target_arch="x86_64"
    • target_os="macos"
  • #[inline]
    • 被外部crate调用的方法默认不会inline, 除非显示指定或者有通用模板参数
    • #[inline(always)]
    • #[inline(never)]

Doc

  • #![doc]等于 //!
  • ///后可以加四个空格或markdown的代码风格 ``` 加入代码作为 Doc-Tests
  • 如果不希望Doc-Tests代码运行, 用 ```no_run
  • 如果不希望Doc-Tests代码编译, 用 ```ignore

Cargo.lock

  • 如果project是个“静态库”, 不用提交Cargo.lock到git中, 每个downstream用户有自己的依赖图dependency graph.
  • 如果project是个动态库(输出是.dll, .dylib, .so), 没有downstream的cargo用户, 必须提交Cargo.lock文件