cratosw

环境与配置

环境与配置

访问环境变量

.NET 通过 System.Environment.GetEnvironmentVariable 在运行时读取环境变量值:

using System;

const string name = "EXAMPLE_VARIABLE";

var value = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(value))
    Console.WriteLine($"Variable '{name}' not set.");
else
    Console.WriteLine($"Variable '{name}' set to '{value}'.");

Rust 在运行时也有同等能力,常用 std::env 模块的 varvar_os

var 返回 Result<String, VarError>

  • 变量存在且为合法 Unicode:返回 Ok(String)
  • 变量不存在或值不是合法 Unicode:返回 Err

var_os 返回 Option<OsString>

  • 变量存在:Some(OsString)
  • 变量不存在:None

OsString 不要求必须是合法 Unicode。

use std::env;

fn main() {
    let key = "ExampleVariable";
    match env::var(key) {
        Ok(val) => println!("{key}: {val:?}"),
        Err(e) => println!("couldn't interpret {key}: {e}"),
    }
}
use std::env;

fn main() {
    let key = "ExampleVariable";
    match env::var_os(key) {
        Some(val) => println!("{key}: {val:?}"),
        None => println!("{key} not defined in the environment"),
    }
}

Rust 还支持编译期读取环境变量。std::env 中的 env! 宏会在编译阶段展开为 &'static str;若变量不存在,会在编译时报错。

fn main() {
    let example = env!("ExampleVariable");
    println!("{example}");
}

在 .NET 中,编译期读取环境变量通常可以借助 source generators 等机制实现,但路径相对不如 Rust 直接。

配置

.NET 中常通过配置提供器(configuration providers)管理配置。 Microsoft.Extensions.Configuration 命名空间及其 NuGet 包提供了多种实现。

配置提供器从不同来源(本质上是键值对)读取数据,并通过 IConfiguration 提供统一视图:

using Microsoft.Extensions.Configuration;

class Example {
    static void Main()
    {
        IConfiguration configuration = new ConfigurationBuilder()
            .AddEnvironmentVariables()
            .Build();

        var example = configuration.GetValue<string>("ExampleVar");

        Console.WriteLine(example);
    }
}

更多示例见官方文档 Configurations provider in .NET

Rust 中可通过第三方 crate 获得类似体验,例如 figmentconfig。 下面示例使用 config

use config::{Config, Environment};

fn main() {
    let builder = Config::builder().add_source(Environment::default());

    match builder.build() {
        Ok(config) => {
            match config.get_string("examplevar") {
                Ok(v) => println!("{v}"),
                Err(e) => println!("{e}")
            }
        },
        Err(_) => {
            // something went wrong
        }
    }
}

On this page