1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

envファイルの内容をグローバル変数として定義する

Last updated at Posted at 2023-01-05

環境

  • macOS 13.1
  • rustc 1.65.0

他言語のようには定義できない...

Pythonの場合

constants.py
import os
from dotenv import load_dotenv

load_dotenv()

XXX = os.getenv("XXX")

Rustで書こうとするとPythonのようには書けません。

constants.rs
use std::env::{self, VarError};

pub static XXX: Result<String, VarError> = env::var("xxx");
error[E0015]: cannot call non-const fn `std::env::var::<&str>` in statics
  --> src/constants.rs:36:45
   |
36 | pub static XXX: Result<String, VarError> = env::var("xxx");
   |                                            ^^^^^^^^^^^^^^^
   |
   = note: calls in statics are limited to constant functions, tuple structs and tuple variants
   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell

E0015の詳細を読み解くと、定数として定義する場合は初期化する際にconstant expressionを用いた方法でないといけないとあり、env::var("xxx")はconst functionではないためこのようには定義できません。

これを修正できる案として、エラーメッセージに以下の内容が書いてあります。

   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell

once_celllazy_staticに取って代わるクレートで、lazy_staticはマクロを用いるのに対し、once_cellはマクロを用いずに以下のように書けます。

constants.rs
use std::env;
use once_cell::sync::Lazy;

pub static XXX: Lazy<String> = Lazy::new(|| env::var("xxx").unwrap());

一つの変数を読み取るのであれば上記方法をとってもいいかもしれませんが、複数の変数を読み取るのであればConfigクレートも一緒に使う方が楽かもしれません。

envファイルの内容をグローバル変数として定義する

使用するクレイト

Cargo.toml
dotenv = "0.15.0"
serde = "1.0.151"
config = "0.13.3"
once_cell = "1.17.0"

envファイル

.env
xxx="hello from .env"

コード

constants.rs
use config::ConfigError;
use dotenv::dotenv;
use once_cell::sync::Lazy;
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Config {
    // .envファイルから読み取る値をフィールドに定義する
    pub xxx: String,
}

impl Config {
    // 環境変数よりConfigを作成し、返却する
    pub fn from_env() -> Result<Self, ConfigError> {
        let cfg = config::Config::builder()
            .add_source(config::Environment::default())
            .build()?;

        cfg.try_deserialize()
    }
}

pub static CONFIG: Lazy<Config> = Lazy::new(|| {
    dotenv().expect("Cannot find .env file");
    Config::from_env().expect("Failed to load config")
});

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?