dotenv().ok()是什么意思?

13

我正在使用基于PostgreSQL的Diesel ORM封装。我在遵循他们网站上的指南,其中有以下代码:

pub fn establish_connection() -> PgConnection {
     dotenv().ok();

     let database_url = env::var("DATABASE_URL")
         .expect("DATABASE_URL must be set");
     PgConnection::establish(&database_url)
         .expect(&format!("Error connecting to {}", database_url))
}

我通过dotenv文档了解到dotenv()的功能——它会加载env文件。在源代码中,我看到dotenv()返回一个Result。那么ok()是什么意思呢?它是否展开了结果?如果是,为什么不使用unwrap()呢?


请参阅文档以获取标准库版本。diesel的定义可能基于此。ok方法也可能是如此。unwrap可能会导致panic,但ok不会,因此调用者可以处理失败情况。 - joel
1
请注意,使用ok()并不是用于处理失败情况,而是用于忽略失败情况。在处理失败时,通常不会调用ok()(因为它会丢弃错误信息),而是直接匹配返回的Result - user4815162342
1个回答

9

这是一种忽略未能加载dotenv环境文件而产生错误的方法。

dotenv()返回一个Result类型。调用Result::ok可以将Result转换为Option类型。使用这个Option就不会触发未使用Result的警告。

为什么不使用unwrap()

因为您不希望出现失败的情况。在生产环境中,您应该需要环境文件,而是使用实际的环境变量。如果您使用了unwrap,那么您的服务将立即在生产环境下失败。这种情况曾经发生在我身上,非常不幸。


1
你认为在生产代码中使用ok()来消除警告是一个好的做法吗?这似乎也会在文件中静默忽略例如语法错误(在错误结果的LineParse变体的情况下),或者系统错误,而不仅仅是“文件未找到”(例如由于无效权限而无法读取文件),而这些错误你可能想知道。 - user4815162342
1
在编程中,我认为忽略错误不是一个好的做法。然而对于dotenv来说,忽略错误似乎是可以接受的,因为它只会在开发环境中出现,风险较低。@user4815162342 - Shepmaster
我明白你的意思,这个想法在生产中不是问题。我想知道像 Diesel 指南这样广泛使用(并且被复制/引用)的文档是否应该推广这种模式。也许它至少应该显示错误,就像 dotenv().map_err(|e| eprintln!("dotenv: {}", e)).ok() 一样。(我不确定当文件不存在时是否会打印错误。)如果对更好的习惯用语(如果有的话)达成共识,我可以发送一个 PR 来更改指南。 - user4815162342
@user4815162342 我预见到的一个问题是Diesel不想专注于dotenv,而是专注于Diesel特定的代码。让dotenv的错误处理变得更长会分散注意力。另一种方法是修改dotenv,使“致命”错误报告为此类错误,而“警告”错误可以被忽略。这样做的缺点是需要库对什么是/不是致命错误有自己的看法。 - Shepmaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接