模块系统
Valkyrie 采用基于命名空间(namespace)和导入(using)的模块系统,提供灵活的代码组织和依赖管理方式。
命名空间声明
基本命名空间
valkyrie
# 声明命名空间
namespace math.geometry {
class Point {
x: f64,
y: f64,
}
distance(p1: Point, p2: Point) -> f64 {
let dx = p1.x - p2.x
let dy = p1.y - p2.y
(dx * dx + dy * dy).sqrt()
}
}嵌套命名空间
valkyrie
namespace graphics {
namespace shapes {
class Circle {
center: Point,
radius: f64,
}
class Rectangle {
top_left: Point,
width: f64,
height: f64,
}
}
namespace colors {
class RGB {
r: u8,
g: u8,
b: u8,
}
let RED: RGB = class { r = 255, g = 0, b = 0 }
let GREEN: RGB = class { r = 0, g = 255, b = 0 }
let BLUE: RGB = class { r = 0, g = 0, b = 255 }
}
}导入系统
基本导入
valkyrie
# 导入整个命名空间
using math.geometry.*
micro main() {
let p1 = new Point { x: 0.0, y: 0.0 }
let p2 = new Point { x: 3.0, y: 4.0 }
let dist = distance(p1, p2)
println("Distance: ${dist}")
}选择性导入
valkyrie
# 导入特定项目
using math.geometry.{Point, distance}
using graphics.colors.{RED, GREEN, BLUE}
# 导入并重命名
using math.geometry.Point as GeomPoint
using graphics.shapes.Point as ShapePoint
micro create_points() {
let geom_point = new GeomPoint { x: 1.0, y: 2.0 }
let shape_point = new ShapePoint { x: 3.0, y: 4.0 }
}通配符导入
valkyrie
# 导入命名空间中的所有公开项目
using math.geometry.*
using graphics.colors.*
# 谨慎使用,可能导致命名冲突
micro example() {
let point = new Point { x: 0.0, y: 0.0 }
let color = RED
}可见性控制
访问修饰符
valkyrie
namespace database {
# 公开结构体
class Connection {
# 私有字段
host: String,
port: u16,
# 公开字段(显式声明)
public timeout: Duration,
}
# 包内可见
class InternalConfig {
secret_key: String,
}
# 私有函数(默认就是私有的)
validate_connection(conn: &Connection) -> bool {
# 内部验证逻辑
true
}
# 公开函数
connect(host: String, port: u16) -> Result<Connection, Error> {
let conn = new Connection { host, port, timeout: Duration::seconds(30) }
if validate_connection(&conn) {
Fine(conn)
} else {
Fail(Error::InvalidConnection)
}
}
}重新导出
valkyrie
namespace api {
# 重新导出其他模块的类型
using database.{Connection, Error}
using auth.{User, Session}
# 提供统一的 API 接口
create_authenticated_connection(credentials: Credentials) -> Result<(Connection, Session), Error> {
let session = auth::login(credentials)?
let connection = database::connect("localhost", 5432)?
Fine((connection, session))
}
}文件路径无关的模块
逻辑模块组织
Valkyrie 的模块系统不依赖文件路径,而是基于逻辑命名空间:
valkyrie
# 文件: src/geometry.val
namespace math.geometry {
class Point { x: f64, y: f64 }
}
# 文件: src/algebra.val
namespace math.algebra {
class Matrix { data: [[f64]] }
}
# 文件: src/utils.val
namespace math.geometry { # 扩展已存在的命名空间
origin() -> Point {
new Point { x: 0.0, y: 0.0 }
}
}模块声明文件
valkyrie
# 文件: math.module.val
# 声明模块的公开接口
module math {
namespace geometry {
class Point
distance(Point, Point) -> f64
origin() -> Point
}
namespace algebra {
class Matrix
multiply(Matrix, Matrix) -> Matrix
}
}条件编译和特性
特性门控
valkyrie
namespace network {
# 基础网络功能
class TcpStream { /* ... */ }
# 异步功能(需要 async 特性)
↯cfg(feature = "async")
namespace async {
class AsyncTcpStream { /* ... */ }
connect_async(addr: SocketAddr) -> Future<Result<AsyncTcpStream, Error>> {
# 异步连接实现
}
}
# TLS 支持(需要 tls 特性)
↯cfg(feature = "tls")
namespace tls {
class TlsStream { /* ... */ }
wrap_tls(stream: TcpStream, config: TlsConfig) -> Result<TlsStream, TlsError> {
# TLS 包装实现
}
}
}平台特定代码
valkyrie
namespace platform {
# 通用接口
trait FileSystem {
read_file(path: String) -> Result<String, IoError>
write_file(path: String, content: String) -> Result<(), IoError>
}
# Windows 实现
↯cfg(target_os = "windows")
namespace windows {
class WindowsFileSystem
imply FileSystem for WindowsFileSystem {
read_file(path: String) -> Result<String, IoError> {
# Windows 特定实现
}
}
}
# Unix 实现
↯cfg(any(target_os = "linux", target_os = "macos"))
namespace unix {
class UnixFileSystem
imply FileSystem for UnixFileSystem {
read_file(path: String) -> Result<String, IoError> {
# Unix 特定实现
}
}
}
}依赖管理
外部依赖
valkyrie
# 项目配置文件: valkyrie.toml
[dependencies]
serde = "1.0"
tokio = { version = "1.0", features = ["full"] }
log = "0.4"
[dev-dependencies]
tokio-test = "0.4"
# 在代码中使用外部依赖
using serde.{Encode, Decode}
using tokio.runtime.Runtime
using log.{info, warn, error}
↯derive(Encode, Decode)
class Config {
host: String,
port: u16,
}
micro main() {
let rt = Runtime::new().unwrap()
rt.block_on(async_main())
}
async micro async_main() {
info("Starting application")
# 异步逻辑
}工作空间
valkyrie
# 工作空间配置: Workspace.toml
[workspace]
members = [
"core",
"api",
"cli",
"web"
]
# 共享依赖
[workspace.dependencies]
serde = "1.0"
tokio = "1.0"
# 在子项目中引用工作空间依赖
# core/valkyrie.toml
[dependencies]
serde = { workspace = true }
tokio = { workspace = true }
# 内部依赖
api = { path = "../api" }模块初始化
静态初始化
valkyrie
namespace config {
# 静态配置
static DATABASE_URL: String = @env("DATABASE_URL")
static MAX_CONNECTIONS: i32 = 100
# 延迟初始化
static LOGGER: Lazy<Logger> = Lazy::new({
Logger::new()
.with_level(LogLevel::Info)
.with_output(Output::Stdout)
})
}动态初始化
valkyrie
namespace database {
static mut CONNECTION_POOL: Option<ConnectionPool> = None
# 初始化函数
initialize(config: DatabaseConfig) -> Result<(), Error> {
unsafe {
if CONNECTION_POOL.is_some() {
return Fail(Error::AlreadyInitialized)
}
let pool = ConnectionPool::new(config)?
CONNECTION_POOL = Some(pool)
Fine { value: () }
}
}
# 获取连接函数
get_connection() -> Result<Connection, Error> {
unsafe {
CONNECTION_POOL
.as_ref()
.ok_or(Error::NotInitialized)?
.get_connection()
}
}
}测试模块
单元测试
valkyrie
namespace math.geometry {
# 距离函数
distance(p1: Point, p2: Point) -> f64 {
let dx = p1.x - p2.x
let dy = p1.y - p2.y
(dx * dx + dy * dy).sqrt()
}
# 测试模块
↯cfg(test)
namespace tests {
using super.*
↯test
test_distance_same_point() {
let p = new Point { x: 1.0, y: 2.0 }
let dist = distance(p, p)
@assert_equal(dist, 0.0)
}
↯test
test_distance_different_points() {
let p1 = new Point { x: 0.0, y: 0.0 }
let p2 = new Point { x: 3.0, y: 4.0 }
let dist = distance(p1, p2)
@assert_equal(dist, 5.0)
}
}
}集成测试
valkyrie
# 文件: tests/integration.val
using myapp.api.*
using myapp.database.*
↯test
micro test_full_workflow() {
# 设置测试环境
let config = TestConfig::default()
initialize_test_database(config)
# 执行测试
let user = create_user("alice", "alice@example.com")
↯assert_true(user.is_ok())
let found_user = find_user_by_email("alice@example.com")
↯assert_true(found_user.is_some())
# 清理
cleanup_test_database()
}最佳实践
模块设计原则
- 单一职责: 每个模块应该有明确的职责
- 低耦合: 模块间依赖应该最小化
- 高内聚: 相关功能应该组织在同一模块中
- 接口稳定: 公开接口应该保持稳定
命名约定
valkyrie
# 好的命名空间组织
namespace myapp {
namespace core { # 核心功能
namespace types # 基础类型
namespace traits # 特征定义
namespace utils # 工具函数
}
namespace services { # 业务服务
namespace user # 用户服务
namespace auth # 认证服务
namespace payment # 支付服务
}
namespace adapters { # 适配器层
namespace database # 数据库适配器
namespace http # HTTP 适配器
namespace cache # 缓存适配器
}
}版本兼容性
valkyrie
namespace api {
# 版本化 API
namespace v1 {
class User {
id: i64,
name: String,
}
get_user(id: i64) -> Option<User> {
# v1 实现
}
}
namespace v2 {
class User {
id: i64,
name: String,
email: String, # 新增字段
}
get_user(id: i64) -> Option<User> {
# v2 实现
}
# 向后兼容
get_user_v1(id: i64) -> Option<v1::User> {
get_user(id).map({ v1::User {
id: u.id,
name: u.name,
})
}
}
# 当前版本别名
using v2.*
}