结构上的方法定义失败 "use of undeclared identifier error"

Method definition on struct fails with "use of undeclared identifier error"

我正在学习 zig,我有一些简单的代码,我尝试在结构上声明一个方法并尝试调用该方法

这是代码

pub fn main() void {
    const Example = struct {
        a: i8,
        b: i8,
        c: u6 = 5,

        fn prettyPrint(self: *Example) void {
            std.debug.print(" a ---> {}\n b ---> {}\n c ---> {}", .{self.a, self.b, self.c});
        }
    };

    var ex: Example = .{.a = 1, .b =1};
    ex.prettyPrint();
}

但失败并出现以下错误

zig run ziggity.zig
ziggity.zig:29:31: error: use of undeclared identifier 'Example'
        fn prettyPrint(self: *Example) void {
                              ^

我使用的是 zig 版本 0.10.0-dev.2024+d127c1d59

这里好像出了什么问题?

这是因为 main 函数在运行时执行,并且在您定义 prettyPrint 时尚未计算。 要解决此问题,请将 Example 移到您的主要功能之外。

这里的问题与不同类型范围之间的标识符查找有何不同有关。

container/global 作用域的变量声明与局部作用域的变量声明不同,因为在前一种情况下,最终绑定到的标识符在其定义中可用,而在后一种情况,事实并非如此。这可以在以下示例中说明:

const bar = blk: {
    // // compile error for shadowing 'bar'.
    // var bar: u32 = 4;
    // bar += 1;
    // break :blk bar;
    break :blk 5;
};

pub fn main() !void {
    const baz = blk: {
        // fine, because 'baz' is not in scope yet.
        var baz: u32 = 5;
        baz -= 1;
        break :blk baz;
    };
    _ = baz;
}

如果您取消注释第一行并注释最后一行,第一块,您会注意到编译错误。从这里应该很容易推断出您的问题是什么: Example 在其自己的定义中不可用,因为它是在本地范围内声明的。此处的解决方法是改用 @This(),或者您可以在 Example.

中声明 const Example = @This();const Self = @This();

编辑:我还应该提一下,我实际上并不知道这是否是有意为之的行为。我觉得可能是,但我无法在 langref 中找到任何明确说明这一点的内容,并且在多次遇到它之后只是熟悉了这种行为。