cargo 项目管理

 

cargo 新建/运行项目、指定依赖以及依赖版本、测试项目和模块,以及 toml 语法

cargo 新建/运行项目、指定依赖以及依赖版本、测试项目和模块,以及 toml 语法

新建

  • cargo new proj --bin
  • cargo new libporj --lib

cargo只是一个包管理工具,并不是编译器 cargo build --verbose 查看详细编译过程

运行

  • cargo run
  • cargo build --release
    • 结果在 target/release
  • cargo build --debug
    • target/debug

其他

  • cargo check: - 只检查编译错误,适合在开发过程中快速检查语法、类型错误。
  • cargo clean:清理以前的编译结果
  • cargo doc:生成该项目的文档
  • cargo test:单元测试
  • cargo bench:执行benchmark性能测试
  • cargo update:升级所有依赖项的版本,重新生成Cargo.lock文件
  • cargo install:安装可执行程序
    • cargo install cargo-tree:安装一个新的cargo子命令
      • 之后用 cargo tree 所有依赖项的树型结构打印出来
  • cargo uninstall:卸载可执行程序

依赖

  • rust 库:crates.io

  • 添加依赖

      [dependencies]
      time = "0.1.12"
      regex = "0.1.41"
      # 依赖本地路径
      my_proj = { path = "../myproj" }
      # 每次下载最新版本
      rand = { git = "https://github.com/rust-lang-nursery/rand.git" }
      # 指定版本
      rand = { git = "https://github.com/rust-lang-nursery/rand.git", rev = "9f35b8e" }
      # 指定分支
      rand = { git = "https://github.com/rust-lang-nursery/rand.git", branch = "next" }
    
    • rust 代码中导入

        extern crate regex
        use regex::Regex;
              
        let re = Regex::new(...).unwrap()
      
  • 更新库的版本

      $ cargo update # 更新所有依赖
      $ cargo update -p rand # 只更新 rand 包
    

项目文件分布

.
├── Cargo.lock	# 依赖版本
├── Cargo.toml  # 项目信息清单
├── benches	# 项目基准
│   └── large-input.rs
├── examples	# 项目demo
│   └── simple.rs
├── src   # 项目源代码
│   ├── bin	# 其他可执行文件
│   │   └── another_executable.rs
│   ├── lib.rs  # 项目库文件
│   └── main.rs # 项目执行文件
└── tests	# 集成测试
    └── some-integration-tests.rs #单元测试

测试

  • cargo test 搜索

      ├── src   # 单元测试
      │   ├── lib.rs  # 项目库文件
      │   └── main.rs # 项目执行文件
      └── tests	# 集成测试
          └── some-integration-tests.rs
    
  • cargo test foo 特定测试

指定依赖版本

Rust包使用的是语义化版本号(SemVer)。版本含义为:major.minor.patch

  • 版本语义
    • major:有不兼容的改动
    • minor:新增API
  • 示例
    • 1.0.0 以前的版本是不稳定版本
      • 如果出现了不兼容的改动,升级次版本minor号,比如从0.2.15升级到0.3.0
    • 1.0.0版本之后
      • 如果出现了不兼容的改动,需要升级主版本号major
      • 如果是兼容性的增加API,且是增加公开的API情况,应该升级次版本号minor
  • 版本的模糊匹配
    • 补注号(^)
      • 允许新版本号在不修改[major,minor,patch]中最左边非零数字的情况下才能更新
    • 波浪线(~)
      • 允许修改[major,minor,patch]中没有明确指定的版本号
      • ~1.2.3 等价于 [1.2.3, 1.3.0)
      • ~1.2 等价于 [1.2.3, 1.3.0)
    • 通配符(*)
      • 可以用在[major,minor,patch]的任何一个上面
      • 1.* 等于 `[1.0.0, 2.0.0)
    • 手动指定
      • >= 1.2.3, > 1.2.3, < 2.0.0, =1.2.3

crate 和 mod

  • crate是Rust中的独立编译单元。每个crate对应生成一个库或者可执行文件(如.lib .dll .so .exe等)
  • mod 简单理解就是命名空间
  • 区别
    • Rust里面,crate才是一个完整的编译单元
    • rustc编译器必须把整个crate的内容全部读进去才能执行编译,
    • rustc不是基于单个的rs文件或者mod来执行编译的

toml 语法规范

注释

井号将此行剩下的部分标记为注释

# 这是一个全行注释
key = "value"  # 这是一个行末注释
another = "# 这不是一个注释"

键值对

  • 键名可以是裸露的,引号引起来的,或点分隔的

      key = "value"
      bare-key = "value"
      1234 = "value"
        
      "127.0.0.1" = "value"
      "character encoding" = "value"
      "ʎǝʞ" = "value"
      'quoted "value"' = "value"
      "" = "空"     # 正确但不鼓励
    
  • 点分隔键是一系列通过点相连的裸键或引号键

      physical.color = "橙色"
      physical.shape = "圆形"
      site."google.com" = true
    
    • 相当于json

        {
          "physical": {
            "color": "橙色",
            "shape": "圆形"
          },
          "site": {
            "google.com": true
          }
        }
      
  • 可以直接对下级赋值

      # 这使“fruit”键作为表存在。
      fruit.apple.smooth = true
        
      # 所以接下来你可以像中这样对“fruit”表添加内容:
      fruit.orange = 2
        
      # 这将 fruit.apple 的值定义为一个整数。
      fruit.apple = 1
        
      # 但接下来这将 fruit.apple 像表一样对待了。
      # 整数不能变成表。
      fruit.apple.smooth = true
    
    • 注意

        3.14159 = "派"
      
      • 相当于 json

          { "3": { "14159": "派" } }
        

        ### 字符串

        • 四种方式来表示字符串

          • ""的单行

              str = "我是一个字符串。\"你可以把我引起来\"。姓名\tJos\u00E9\n位置\t旧金山。"
            
          • """ 的多行

              str1 = """
              玫瑰是红色的
              紫罗兰是蓝色的"""
            
            • 相当于

                # 在 Unix 系统,上面的多行字符串可能等同于:
                str2 = "玫瑰是红色的\n紫罗兰是蓝色的"
                                      
                # 在 Windows 系统,它可能等价于:
                str3 = "玫瑰是红色的\r\n紫罗兰是蓝色的"
              
            • 行末反斜杠

                str1 = "那只敏捷的棕狐狸跳过了那只懒狗。"
                str3 = """\
                       那只敏捷的棕\
                       狐狸跳过了\
                       那只懒狗。\
                       """
              
          • 原始字符串 ''

              # 所见即所得。
              winpath  = 'C:\Users\nodejs\templates'
              # 没有转义
              regex    = '<\i\c*\s*>'
            
          • 多行原始字符串 '''

              regex2 = '''I [dw]on't need \d{2} 
              apples'''
            
        • 数值

          • 整数

              int1 = +99
              int2 = -17
              int5 = 1_000
              # 带有 `0x` 前缀的十六进制
              hex1 = 0xDEADBEEF
              # 带有 `0o` 前缀的八进制
              oct1 = 0o01234567
              # 带有 `0b` 前缀的二进制
              bin1 = 0b11010110
            
          • 浮点数

              # 小数
              flt1 = +1.0
              # 指数
              flt4 = 5e+22
              # 综合
              flt7 = 6.626e-34
              # 下划线
              flt8 = 224_617.445_991_228
            
          • bool

              bool1 = true
              bool2 = false
            
    • 列表

        contributors = [
          "Foo Bar <foo@example.com>",
          { 
          	name = "Baz Qux", 
          	email = "bazqux@example.com", 
            url = "https://example.com/bazqux" }
        ]
      
      • 表(也被称为哈希表或字典)是键值对的集合
        [table-1] # 表头
        key1 = "some string"
        key2 = 123
      
      • 表名的规则与键名相同

          [dog."tater.man"]
          type.name = "哈巴狗"
        
          { "dog": { "tater.man": { "type": { "name": "哈巴狗" } } } }
        
        • dog, 子表 "tater.man"
      • 顶层表,又被称为根表,于文档开始处开始并在第一个表头(或文件结束处)前结束

          # 顶层表开始。
          name = "Fido"
          breed = "哈巴狗"
                    
          # 顶层表结束
          [owner]
        
      • 点分隔键为最后一个键名前的每个键名都创建成一个表

          fruit.apple.color = "红色"
          # 定义一个名为 fruit 的表
          # 定义一个名为 fruit.apple 的表
        
      • 行表

          name = { first = "汤姆", last = "普雷斯顿—维尔纳" }
        
    • 表组

      • 把表名写在双方括号里

          [[products]]
          name = "锤子"
          sku = 738594937
                    
          [[products]]  # 数组里的空表
                    
          [[products]]
          name = "钉子"
          sku = 284758393
                    
          color = "灰色"
        
          {
            "products": [
              { "name": "锤子", "sku": 738594937 },
              { },
              { "name": "钉子", "sku": 284758393, "color": "gray" }
            ]
          }
        
      • 表的元素

          [[fruits]]
          name = "苹果"
                    
          [fruits.physical]  # 子表
          color = "红色"
          shape = "圆形"
                    
          [[fruits.varieties]]  # 嵌套表数组
          name = "蛇果"
                    
          [[fruits.varieties]]
          name = "澳洲青苹"
                    
          [[fruits]]
          name = "香蕉"
                    
          [[fruits.varieties]]
          name = "车前草"
        
          {
            "fruits": [
              {
                "name": "苹果",
                "physical": {
                  "color": "红色",
                  "shape": "圆形"
                },
                "varieties": [
                  { "name": "蛇果" },
                  { "name": "澳洲青苹" }
                ]
              },
              {
                "name": "香蕉",
                "varieties": [
                  { "name": "车前草" }
                ]
              }
            ]
          }