Rust :mod.rs和lib.rs中use的作用

一、mod.rs和lib.rs

mod.rs往往是把同一目录下的n个rs文件综合在一起的有效方式;

lib.rs是一个库或子库层次综合在一起的有效方式;

下面举个实例来说明。生成一个rusttoc本地库(由cargo new rusttoc --lib所生成),目录结构如下:

复制代码
songroom@staff-NB-146:~/myffi/rusttoc/src$ ls -R
.:
bar  lib.rs

./bar:
data.rs  ffi.rs  mod.rs

其中,data.rs文件内容如下:

复制代码
#[derive(Debug)]
pub struct Tick;
pub trait GetBar{
    fn get_bar(&self)->Vec<Bar>;
}
#[derive(Debug)]
pub struct Bar{
    open:f64,
    close:f64,
    min:f64,
    max:f64,
}
impl Bar{
    pub fn new() ->Self{
        Bar { open: 0.0, close: 0.0, min: 0.0, max: 0.0 }
    }
}

其中,ffi.rs文件内容如下:

复制代码
use std::os::raw::{c_int,c_double};
extern "C"{
    fn abs(num:c_int) ->c_int;
    fn sqrt(x:c_double) ->c_double;
}
#[no_mangle]
pub extern "C" fn rfn_for_c(){
    println!("call from rust fn abs :{}",unsafe{abs(-6)});
    println!("call from rust fn sqrt :{}",unsafe{sqrt(36.0)});
}

此外,在上面rusttoc库中,在src目录下,除了有lib.rs文件,还有一个bar文件夹,在这个文件夹下,还有3个.rs文件,其中包括一个mod.rs文件。

很显然,mod.rs是把data.rs和ffi.rs综合在一起对外开放的文件。

而lib.rs是在rusttoc这个层次,综合起来的一个对外开放的文件。

当然,如果一个库中,包含若干个子库,那也会存在多个不同层次的lib.rs的文件。

二、use来管理库内容的对外开放

在每层mod.rs和lib.rs文件中,要通过use来约束对外开放的程度和范围。

mod.rs文件

复制代码
pub mod ffi;
pub mod data;
pub use ffi::rfn_for_c;
pub use data::{Bar,GetBar};//这里设置Tick不暴露

lib.rs文件

复制代码
pub mod bar;
pub use bar::*;

在mod.rs中,通过pub use来约束ffi.rs和data.rs在此库对外开放(或暴露)的范围,在这里为rfn_for_c函数,以及Bar,以及GetBar。而没有进来的Tick,则表明不对外开放(暴露)。

在lib.rs层次,再次明确对外开放的层次,使用use表统一表明,各个mod.rs或子lib.rs的统一对外开放。

如果没有use安排,以上均会处于关闭状态,均无法以本地库或外地库的方式来调用。当然,在use前,还要声明一下各mod。

三、另外一种方式:include

除了mod.rs,lib.rs之外,还有一种特别的导入形式,即include。它可以把不同形式文件的内容导入到当到的工作空间。

下面,在test文件夹下,放了两个不同后缀的文件。

复制代码
songroom@staff-NB-146:~/myffi/test$ ls -R
.:
bind.rs  const.txt

bind.rs

复制代码
#[derive(Debug)]
struct Student{
    name : String,
    age:i32,
}

const.txt

复制代码
const MIN_VALUE:f64 =30000.0_f64;

四、调用库和include导入

另一个rust 二进制工程文件中,有main.rs如下:

复制代码
include!("../../test/bind.rs");
include!("../../test/const.txt");
pub use rusttoc::*;
struct Strategy;
//实现本地库中的trait
impl GetBar for Strategy{
    fn get_bar(&self)->Vec<Bar>{
        vec![Bar::new()]
    }
}

fn main() {
    let student = Student{name: "wowotuo".to_string(),age:18};
    //let tick = Tick;
    let bar = Bar::new();
    let strategy = Strategy;
    println!("bar:{:?}",bar);
    println!("strategy ->get_bar:{:?}",strategy.get_bar());//调用trait
    //let tick = Tick; //因为mod.rs中没有开放Tick的访问权限,故不能访问
    //println!("tick:{:?}",tick);
    println!("student :{:?}",student);
    rfn_for_c();
    println!("const :{:?}",MIN_VALUE);
    println!("Hello, world!");
}

另外,在这个工程下,cargo.toml文件应加下如下部分,表明需要导入本地库,并指明相应的路径:

复制代码
[dependencies.rusttoc]
path = "../rusttoc" #库的位置

这样,就是main.rs中导入了rusttoc库,以及include了两个文件进来了。

复制代码
songroom@staff-NB-146:~/myffi/work/src$ cargo run --release
   Compiling work v0.1.0 (/home/songroom/myffi/work)
    Finished release [optimized] target(s) in 1.68s
     Running `/home/songroom/myffi/work/target/release/work`
bar:Bar { open: 0.0, close: 0.0, min: 0.0, max: 0.0 }
strategy ->get_bar:[Bar { open: 0.0, close: 0.0, min: 0.0, max: 0.0 }]
student :Student { name: "wowotuo", age: 18 }
call from rust fn abs :6
call from rust fn sqrt :6
const :30000.0
Hello, world!

上面分别实现本地库中trait,调用了const,相关函数和struct等。

相关推荐
Gofarlic_oms14 小时前
利用API实现ANSYS许可证管理自动化集成
运维·服务器·开发语言·matlab·自动化·负载均衡
AI+程序员在路上5 小时前
VS Code 完全使用指南:下载、安装、核心功能与 内置AI 编程助手实战
开发语言·人工智能·windows·开源
invicinble5 小时前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
小码哥_常5 小时前
MyBatis-Plus:让数据库操作飞起来的神器
后端
catchadmin5 小时前
使用 PHP TrueAsync 改造 Laravel 协程异步化的可行路径
开发语言·php·laravel
wbs_scy5 小时前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
2301_811274316 小时前
基于SpringBoot的智能家居管理系统
spring boot·后端·智能家居
AI人工智能+电脑小能手6 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
舒一笑6 小时前
我把设备指纹生成逻辑拆开了:它到底凭什么区分不同设备?
后端·程序员·掘金技术征文
Nicander6 小时前
多数据源下@transcation事务踩坑
java·后端