3

我试图用通用算法实现向量代数,最后玩了迭代器。我发现了两个不明显和意外行为的例子:

  1. 如果我有指向p带有 field 的结构(实例)的指针,我可以像(而不是)fi一样简单地访问该字段p.fip.*.fi
  2. 如果我有一个“成员”函数fun(this: *Self)(where Self = @This())和一个结构实例s,我可以像调用函数一样简单s.fun()(而不是(&s).fun()

我的问题是:

  1. 它是否在某处记录(或以任何方式提及)?我查看了来自ziglearn.org的语言参考和指南,但没有找到任何东西
  2. 我们在这些例子中观察到了什么?两种特殊情况的语法糖,还是有更一般的规则可以推断出这种行为?
  3. 还有更多奇怪指针行为的例子吗?
4

2 回答 2

2

对于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]});
}

AFAIK 这些是这种行为的仅有的三个实例。在所有其他情况下,如果某些东西需要一个指针,你必须明确地提供它。即使将数组传递给接受切片的函数,也必须显式获取数组的指针。

权威的信息来源是语言参考,但快速检查,似乎没有专门的段落。也许有一些我错过的例子。
https://ziglang.org/documentation/0.8.0/

于 2021-07-20T11:57:05.213 回答
1

我首先通过 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 课程对一些语言主题进行了相当深入的研究,因此如果您有兴趣,绝对可以检查一下。

关于其他语法:正如前面提到的答案,您不需要取消引用数组指针。我不确定其他任何事情(我认为函数指针的工作方式相同,但我只是运行了一些测试,但它们没有。)

于 2021-10-22T20:47:46.297 回答