簡體   English   中英

如何在 Rust 2015 中從一個模塊到另一個模塊進行基本的函數導入/包含?

[英]How do I do a basic import/include of a function from one module to another in Rust 2015?

我找不到如何將函數從一個文件(模塊)包含(或導入、注入或其他詞)到另一個文件(模塊)。

我開始一個新項目

$ cd ~/projects
$ cargo new proj --bin
$ cd proj
$ tree
.
|
-- Cargo.toml
-- src
   |
   -- main.rs

我修改main.rs並使用以下代碼創建一個新文件a.rs (在src目錄中):

主文件

fn main() {
    println!("{}", a::foo());
}

a.rs

pub fn foo() -> i32 { 42 }

我用cargo run運行項目並得到錯誤:

error[E0433]: failed to resolve: use of undeclared type or module `a`
 --> src/main.rs:2:20
  |
2 |     println!("{}", a::foo());
  |                    ^ use of undeclared type or module `a`

看來我需要以某種方式導入a 我嘗試將以下內容作為第一行添加到main.rs

  • use a;

     error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a; | ^ no `a` in the root
  • use a::*;

     error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::*; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
  • use a::foo;

     error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::foo; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
  • extern crate a; use a::foo;

     error[E0463]: can't find crate for `a` --> src/main.rs:1:1 | 1 | extern crate a; | ^^^^^^^^^^^^^^^ can't find crate
  • extern crate proj; use proj::a::foo;

     error[E0463]: can't find crate for `proj` --> src/main.rs:1:1 | 1 | extern crate proj; | ^^^^^^^^^^^^^^^^^^ can't find crate

我已經閱讀 了指南,但仍然無法弄清楚如何進行導入。

在 mainish 模塊(main.rs、lib.rs 或 subdir/mod.rs)中,您需要編寫mod a; 對於要在整個項目(或子目錄)中使用的所有其他模塊。

在任何其他模塊中,您需要編寫use a; use a::foo;

您遠不是唯一對此感到困惑的人,當然可以做得更好,但是對模塊系統的任何更改都會因為“太混亂”而被拒絕。

編輯:此答案是為“Rust 2015”語言標准編寫的。 對“Rust 2018”標准進行了更改,請參閱此博客文章版本指南

在 Rust 中,有一些關鍵字來處理模塊:

extern crate

extern crate填補了 Cargo 和 Rust 之間的空白。 我們在一個 .rs 文件中編寫代碼,這個文件可以用rustc編譯。 Cargo 將管理外部依賴項並調用rustc extern crate ...行告訴編譯器尋找這個命名空間,所以它是明確的。

編者注- 如果您使用的是 Rust 2018 版本,則在許多情況下不需要extern crate

mod

mod有兩個用途:

  • 當與花括號一起使用時,它聲明了一個模塊(命名空間)。
  • 當僅使用名稱時,它將在本地文件系統中查找模塊。

模塊可以是:

  • 擴展名為 .rs 的文件
  • 包含一個名為 mod.rs 的文件的文件夾

use

use導入一個命名空間。 我們需要在使用之前宣布我們將使用什么。 use 子句非常嚴格,如果我們聲明use module1::moduleA; 沒有其他模塊module1將可用,但moduleA 星號 ( * ) 可用於使用模塊中的所有內容: use module1::*; . 也可以使用集合: use module1::{moduleA, moduleB};

一個例子:

| main.rs
|- module1
      |- mod.rs
      |- moduleA.rs
      |- moduleB.rs

mod.rs 包含:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module

main.rs 包含:

///  ======
// use what Cargo downloaded
extern crate that_one_thing_i_need;

///  ======

mod module1; // declare a child module

// some local stuff I want to scope
mod local {
    pub fn my_function() {}
}

//   ======

// make the symbols locally available:
use module1::moduleA::*;
use module1::moduleB::{functionX, moduleY, typeZ};

// we still need to announce what stuff from the external crate
// we want to use:
// We can do local aliases that will be valid in this one file.
use that_one_thing_i_need::fancy_stuff as fs;

///  ======

fn main() {
    // we can use anything here from the namespaces we are using:
    //      moduleA
    //      functionX
    //      moduleY
    //      typeZ
    //      fs

    // We can access stuff by navigating from the outermost visible
    // module name
    local::my_function();
}

符號只能在模塊內使用。 如果你想跨越這個障礙(即使是在本地聲明的模塊上),我們需要使用關鍵字pub將它們公開。

我參加聚會很晚,但是將代碼拆分為多個文件而不會過多影響范圍的一種方法如下。

想象一下這樣的文件夾結構,對於書籍處理庫:

src/
  lib.rs
  author.rs
  book.rs

你可以做:

// lib.rs
// --------------
mod author;
use author::*;
mod book;
use book::*;

// author.rs
// --------------
struct Author {
    name: String,
    birth_year: i32,
}

// book.rs
// --------------
use super::*;

struct Book {
   title: String,
   author: Author,  // Author is in scope
   isbn: i64,
}

這種結構模擬 Go 模塊(文件夾中的所有內容似乎都在同一范圍內)。

另一種方法是(更像python風格):

// lib.rs
// --------------
mod author;
mod book;

// book.rs
// --------------
// either so, to import everything
use super::*;
// or so, one line per peer-module
use super::author;

struct Book {
   title: String,
   author: author::Author,  // Author is in scope
   isbn: i64,
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM