一段代码演示初学者容易掉坑的“comptime 副作用陷阱”

先看这段代码:

c 复制代码
const std = @import("std");
const print = std.debug.print;

pub fn main() !void {
    var data: i32 = 99;
    const T = @TypeOf(foo(i32, &data));
    print("type: {}\n", .{T});
    print("data = {d}\n", .{data});
}

fn foo(T: type, ptr: *T) T {
    ptr.* += 1;
    return ptr.*;
}

这段 Zig 程序看起来会调用 foo(),修改了 data,然后打印出来,但实际运行时你会发现:

ini 复制代码
type: i32
data = 99

data 根本没有变成 100!这让人非常困惑:明明写了 foo(i32, &data),为什么 ptr.* += 1 没有生效?

根本原因:foo 被当做了 comptime 函数调用! 关键代码在这里:

zig 复制代码
const T = @TypeOf(foo(i32, &data));

@TypeOf(...) 是一个 编译期内置函数,它只关心表达式的类型,不关心运行时的副作用。

Zig 的规则是:

只要一个表达式的结果在编译期是已知的,编译器就有权在编译期就把整个表达式求值完成(包括函数调用),即使这个函数有副作用。

Zig通过对等类型解析,在编译期完成了类型的推导。

如何让它真正修改运行时的 data?

要避免在编译期求值这个调用:

zig 复制代码
pub fn main() !void {
    var data: i32 = 99;

    // 方案1:先调用,再取类型(推荐)
    const result = foo(i32, &data);        // 运行时调用
    const T = @TypeOf(result);             // 现在才 comptime 求类型
    print("type: {}\n", .{T});
    print("data = {d}\n", .{data});        // → 100
}
相关推荐
abcefg_h12 分钟前
MCP 实战指南:如何在项目中使用 Model Context Protocol 及其通信原理
开发语言·后端·golang·mcp
AI多Agent协作实战派16 分钟前
AI多Agent协作系统实战(四十八):改个名,整个AI团队都不认识人了
后端
wei_shuo33 分钟前
KES 故障诊断与应急响应:问题排查、根因分析与应急预案
后端
LinMINGJing00733 分钟前
postgre分区方式
后端
王中阳Go39 分钟前
业务代码凭什么不能直接调 Agent?——我在律所 AI 项目里做的 Harness 运行时治理
人工智能·后端·程序员
SomeB1oody2 小时前
【RustyML入门】7.2. 深入模型持久化
开发语言·后端·机器学习·rust·教程
知几蜗牛2 小时前
0 后端 · 0 数据库 · 0 备案:用 AI 两天搓出的股票管理系统,开源了
前端·后端·llm
风流 少年2 小时前
Spring AI 2.0:阿里云百炼平台(工作流应用)
java·后端·spring
__zRainy__2 小时前
Node系列 · 数据库:单表查询
数据库·后端·mysql·node.js
诺伦2 小时前
Rust 错误处理实战:从 unwrap 到优雅 Result 的进阶之路
开发语言·后端·rust