basic/crate-module/module #770
Replies: 27 comments 23 replies
-
“而结构体的应用场景比较复杂,其中的字段也往往部分在 A 处被使用,部分在 B 处被使用,因此无法确定成员的可见性,那索性就设置为全部不可见,将选择权交给程序员。”,如果结构体的成员默认是私有的话,下面的代码应该通不过编译才对,但是实际上是可以通过编译的。
} |
Beta Was this translation helpful? Give feedback.
-
比如A是父模块,B、C是A的子模块 |
Beta Was this translation helpful? Give feedback.
-
关于模块的可见性,我之前遇到过一个问题,就是私有的内容一般来说就是不需要用户了解使用的,用户只需要使用 pub 内容即可。 举个例子:假设有一个包,公开函数是接受两个地名,然后返回两个地名之间的直线距离。具体实现是:公开函数接受两个地名,然后调用一个私有函数将两个地名转换为经纬度,然后调用另一个私有函数计算两个经纬度之间的距离。 这个例子虽说计算经纬度的距离挺通用的,也许可以抽取成一个独立的包来使用,但实际场景下,可能就不一定了。 所以有没有某种 unsafe 的可能,突破可见性限制去调用另一个模块的私有功能呢?类似于其他语言中的利用反射来调用其他对象上的私有方法? |
Beta Was this translation helpful? Give feedback.
-
这不是个library吗? 为什么可以运行 |
Beta Was this translation helpful? Give feedback.
-
关于结构体和枚举可见性的一点建议
|
Beta Was this translation helpful? Give feedback.
-
pub mod front_of_house { mod front_of_house; pub use crate::front_of_house::front_of_house::hosting; // 我需要写成这样才没有语法错误, rustc 1.64.0 |
Beta Was this translation helpful? Give feedback.
-
在上面的例子中 pub fn eat_at_restaurant() {
} 为什么eat_at_restaurant这个函数前要加pub,而front_of_house前面不用加 |
Beta Was this translation helpful? Give feedback.
-
怎么感觉这章比生命周期啥的还难,例子我都跑不起来😭 |
Beta Was this translation helpful? Give feedback.
-
我是win环境,版本是rustc 1.70.0 (90c541806 2023-05-31),包这边必须 |
Beta Was this translation helpful? Give feedback.
-
https://www.cnblogs.com/fire-cat/p/17578600.html |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
在 front_of_house 同级目录里创建一个与模块(目录)同名的 rs 文件 front_of_house.rs,在新版本里,更建议使用这样的命名方式来避免项目中存在大量同名的 mod.rs 文件( Python 点了个 踩)。 需要更正一下: 在 lib.rs 同级目录里创建一个与模块(目录)同名的 rs 文件 front_of_house.rs,在新版本里,更建议使用这样的命名方式来避免项目中存在大量同名的 mod.rs 文件( Python 点了个 踩)。 |
Beta Was this translation helpful? Give feedback.
-
经过研究发现, mod有两种用法, 一种是后面带大括号的, 是定义mod, 另一种是mod后面跟着一个名字, 是引用mod。 一个rs文件,就是一个天然的mod, 可以在其中定义更小的mod。 引入mod的关键字还是mod, 不像java使用namespace定义,使用import引入。 |
Beta Was this translation helpful? Give feedback.
-
看完可以理解Package, Crate, module的关系。但是没有理解怎么让多个文件组织成一个Crate? |
Beta Was this translation helpful? Give feedback.
-
我的一些疑问:
|
Beta Was this translation helpful? Give feedback.
-
这两种方法怎么感觉没有本质的区别,只是将文件夹种的mod.rs文件移动到了上一级目录下,文件名改为和目录名相同。 |
Beta Was this translation helpful? Give feedback.
-
模块这里很烦,声明要放在父模块里,实现与分离分开,要添加一个模块,需要添加文件、再去父模块里添加声明。 |
Beta Was this translation helpful? Give feedback.
-
我来说一下我的理解:
|
Beta Was this translation helpful? Give feedback.
-
教程里说“ src/main.rs 和 src/lib.rs 被称为包根(crate root),……这两个文件的内容形成了一个模块 crate” // 在lib.rs文件中,mod定义不用单独文件的方式
pub mod A{
pub fn my_method(){}
}
A::my_method(); // 能正确引用
crate::A::my_method(); // 能正确引用
user mycrate::A::my_method; // 能正确引用
// 在 main.rs文件中引用 my_method 函数
// use A::my_method(); // 这个报错
// use crate::A::my_method(); // 这个也报错
use mycrate::A::my_method(); // 这个能正确引用 如果 main.rs 和 lib.rs 的包根crate 是同一个的话,怎么解释 main.rs 里无法用 |
Beta Was this translation helpful? Give feedback.
-
就学过c++和python,感觉模块这东西好像cmake啊,但能编译是真没见过 |
Beta Was this translation helpful? Give feedback.
-
感觉自己又变强了。 |
Beta Was this translation helpful? Give feedback.
-
写了一个mod试图使用其他语言调用,但是怎么调也都是fail……有大神能告诉我问题出现在哪里吗 库公开地址:https://github.com/Mikachu2333/name_exchanger_rslib 代码逻辑简化如下: #[no_mangle]
pub extern "C" fn exchange_inputs(input1: String, input2: String) -> String {
let result_num = process_input::change_name::exchange(input1, input2);
process_input::show_error::switch_error_msg(result_num)
}
pub(crate) mod process_input {
pub(crate) mod metadata_get {
//各种用于获取文件(文件夹)信息的函数
//例如:是否存在,用户输入路径是否为相对路径,是否存在父子目录关系等等,均为pub
pub(crate) mod change_name {
fn make_name(dir: PathBuf, mut other_name: String, ext: String) -> (PathBuf, PathBuf) {
//函数:获取新文件名
}
pub fn exchange(input1:&PathBuf, input2:&PathBuf)->u8{
//具体执行,用到了metadata_get模块中的所有函数和本change_name模块中的make_name函数
返回u8表示是否出现错误以及错误的类型
}
}
}
pub mod show_error {
pub fn switch_error_msg(num: u8) -> String {
//美化错误信息
}
}
}
#[cfg(test)]
mod tests {
fn clear_olds(test_path1: &String, test_path2: &String) {
//创建测试文件
}
#[test]
fn it_works() {
let test_path1 = String::from("D:\\languagelearning\\Rust\\exchange_name_lib\\file1.ext1");
let test_path2 = String::from("D:\\languagelearning\\Rust\\exchange_name_lib\\file2.ext2");
clear_olds(&test_path1, &test_path2);
let run_result = exchange_inputs(test_path1, test_path2);
println!("{}", run_result);
}
} 编译为dll
cpp调用代码如下: #include<iostream>
#include <windows.h>
using namespace std;
typedef string (*func)(string a, string b);
int main()
{
//动态加载 dll
HMODULE hModule = LoadLibraryA("name_exchanger_rs.dll");
if (!hModule)
{
cout << "Error!" << endl;
}
func exchange_fn = func(GetProcAddress(hModule, "exchange_inputs"));
if (exchange_fn != NULL)
{
string r = exchange_fn("D:\\Desktop\\file1.ext1", "D:\\Desktop\\file2.ext2");
cout << r << endl;
}
//释放
FreeLibrary(hModule);
return 0;
} |
Beta Was this translation helpful? Give feedback.
-
如果在 然而,因为没有使用 |
Beta Was this translation helpful? Give feedback.
-
两种方法下的目录结构: 方法1:使用
|
Beta Was this translation helpful? Give feedback.
-
请问在下面这个例子中,为什么要在pub use crate::front_of_house::hosting;前使用mod front_of_house;呢这个原理是什么呀? mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
} |
Beta Was this translation helpful? Give feedback.
-
感觉这个项目组织,不如JAVA的包结构让人容易理解 |
Beta Was this translation helpful? Give feedback.
-
多目录mod感觉很鸡肋,要想把某个目录当作mod还需要建一个同名rs文件来声明其子mod,目录结构本身就体现了mod的层级结构,结果还需要在父mod的rs文件里面声明一下子mod。java的包结构一点没学,就学了C/C++的定义与声明,用前必须先声明(注意是声明,不是use关键字)- -! |
Beta Was this translation helpful? Give feedback.
-
basic/crate-module/module
https://course.rs/basic/crate-module/module.html
Beta Was this translation helpful? Give feedback.
All reactions