一段代码演示初学者容易掉坑的“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
}
相关推荐
Coder_Boy_1 小时前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
Java后端的Ai之路1 小时前
【Spring全家桶】-一文弄懂Spring Cloud Gateway
java·后端·spring cloud·gateway
野犬寒鸦1 小时前
从零起步学习并发编程 || 第七章:ThreadLocal深层解析及常见问题解决方案
java·服务器·开发语言·jvm·后端·学习
Honmaple2 小时前
OpenClaw 实战经验总结
后端
golang学习记2 小时前
Go 嵌入结构体方法访问全解析:从基础到进阶陷阱
后端
NAGNIP3 小时前
程序员效率翻倍的快捷键大全!
前端·后端·程序员
qq_256247053 小时前
从“人工智障”到“神经网络”:一口气看懂 AI 的核心原理
后端
无心水3 小时前
分布式定时任务与SELECT FOR UPDATE:从致命陷阱到优雅解决方案(实战案例+架构演进)
服务器·人工智能·分布式·后端·spring·架构·wpf
用户400188309373 小时前
手搓本地 RAG:我用 Python 和 Spring Boot 给 AI 装上了“实时代码监控”
后端
用户3414081991253 小时前
/dev/binder 详解
后端