zig 结构、指针、字段访问
zig structs, pointers, field access
我试图用通用算法实现向量代数,结果玩弄了迭代器。我发现了两个不明显和意外行为的例子:
- 如果我有指针
p
指向具有字段 fi
的结构(实例),我可以像 p.fi
(而不是 p.*.fi
)一样简单地访问该字段
- 如果我有一个“成员”函数
fun(this: *Self)
(其中 Self = @This()
)和该结构的一个实例 s
,我可以像 [=17= 一样简单地调用该函数](而不是(&s).fun()
)
我的问题是:
- 是否在某处记录(或以任何方式提及)?我查看了 ziglearn.org 的语言参考和指南,但没有找到任何东西
- 我们在这些例子中观察到了什么?两种特殊情况的语法糖,还是有更一般的规则可以从中推断出这种行为?
- 还有更多奇怪指针行为的例子吗?
对于 1 和 2,你是正确的。在 Zig 中,点透明地适用于结构值和结构指针。同样,命名空间函数在调用时也会做正确的事情。
我能想到的唯一其他类似行为是在数组上使用的 []
语法。您可以直接对数组值和数组指针互换使用。这有点等同于点对结构的操作方式。
const std = @import("std");
pub fn main() !void {
const arr = [_]u8{1,2,3};
const foo = &arr;
std.debug.print("{}", .{arr[2]});
std.debug.print("{}", .{foo[2]});
}
据我所知,这是此行为的仅有的三个实例。在所有其他情况下,如果某些东西需要指针,您必须明确提供它。即使将数组传递给接受切片的函数,也必须显式获取数组的指针。
权威的信息来源是语言参考,不过很快查了一下,好像没有专门的段落。也许我错过了一些例子。
https://ziglang.org/documentation/0.8.0/
我首先学习了 ziglings 课程,该课程链接到 ziglang.org。
练习 43 (https://github.com/ratfactor/ziglings/blob/main/exercises/043_pointers5.zig)
// Note that you don't need to dereference the "pv" pointer to access
// the struct's fields:
//
// YES: pv.x
// NO: pv.*.x
//
// We can write functions that take pointer arguments:
//
// fn foo(v: *Vertex) void {
// v.x += 2;
// v.y += 3;
// v.z += 7;
// }
//
// And pass references to them:
//
// foo(&v1);
ziglings 课程对一些语言主题进行了相当深入的探讨,因此如果您有兴趣,不妨一试。
关于其他语法:如前一个答案所述,您不需要取消引用数组指针。我不确定其他任何事情(我认为函数指针的工作方式相同,但我只是 运行 一些测试,但他们没有。)
我试图用通用算法实现向量代数,结果玩弄了迭代器。我发现了两个不明显和意外行为的例子:
- 如果我有指针
p
指向具有字段fi
的结构(实例),我可以像p.fi
(而不是p.*.fi
)一样简单地访问该字段 - 如果我有一个“成员”函数
fun(this: *Self)
(其中Self = @This()
)和该结构的一个实例s
,我可以像 [=17= 一样简单地调用该函数](而不是(&s).fun()
)
我的问题是:
- 是否在某处记录(或以任何方式提及)?我查看了 ziglearn.org 的语言参考和指南,但没有找到任何东西
- 我们在这些例子中观察到了什么?两种特殊情况的语法糖,还是有更一般的规则可以从中推断出这种行为?
- 还有更多奇怪指针行为的例子吗?
对于 1 和 2,你是正确的。在 Zig 中,点透明地适用于结构值和结构指针。同样,命名空间函数在调用时也会做正确的事情。
我能想到的唯一其他类似行为是在数组上使用的 []
语法。您可以直接对数组值和数组指针互换使用。这有点等同于点对结构的操作方式。
const std = @import("std");
pub fn main() !void {
const arr = [_]u8{1,2,3};
const foo = &arr;
std.debug.print("{}", .{arr[2]});
std.debug.print("{}", .{foo[2]});
}
据我所知,这是此行为的仅有的三个实例。在所有其他情况下,如果某些东西需要指针,您必须明确提供它。即使将数组传递给接受切片的函数,也必须显式获取数组的指针。
权威的信息来源是语言参考,不过很快查了一下,好像没有专门的段落。也许我错过了一些例子。
https://ziglang.org/documentation/0.8.0/
我首先学习了 ziglings 课程,该课程链接到 ziglang.org。
练习 43 (https://github.com/ratfactor/ziglings/blob/main/exercises/043_pointers5.zig)
// Note that you don't need to dereference the "pv" pointer to access
// the struct's fields:
//
// YES: pv.x
// NO: pv.*.x
//
// We can write functions that take pointer arguments:
//
// fn foo(v: *Vertex) void {
// v.x += 2;
// v.y += 3;
// v.z += 7;
// }
//
// And pass references to them:
//
// foo(&v1);
ziglings 课程对一些语言主题进行了相当深入的探讨,因此如果您有兴趣,不妨一试。
关于其他语法:如前一个答案所述,您不需要取消引用数组指针。我不确定其他任何事情(我认为函数指针的工作方式相同,但我只是 运行 一些测试,但他们没有。)