一个学习类型擦除接口时发现的奇怪现象 #191
Answered
by
w568w
TongVan520
asked this question in
新手提问
一个学习类型擦除接口时发现的奇怪现象
#191
-
考虑以下代码: const std = @import("std");
test "指针" {
const Base = struct {
const Self = @This();
object: *anyopaque,
interface: struct {
show: *const fn (object: *const anyopaque) void,
},
pub fn show(self: Self) void {
self.interface.show(self.object);
}
};
const Child = struct {
const Self = @This();
number: usize,
pub fn makeBase(self: Self) Base {
return (Base{
.object = @constCast(&self),
.interface = .{
.show = struct {
fn f(object: *const anyopaque) void {
const s: *const Self = @ptrCast(@alignCast(object));
s.show();
}
}.f,
},
});
}
// pub fn makeBase(self: *Self) Base {
// return (Base{
// .object = self,
// .interface = .{
// .show = struct {
// fn f(object: *const anyopaque) void {
// const s: *const Self = @ptrCast(@alignCast(object));
// s.show();
// }
// }.f,
// },
// });
// }
pub fn show(self: Self) void {
std.debug.print("self.number == {d}\n", .{self.number});
}
};
var child = Child{ .number = 114514 };
var base = child.makeBase();
const new_child: *Child = @ptrCast(@alignCast(base.object));
child.show();
base.show();
new_child.show();
std.debug.print("&child == \n\t{*}\n", .{&child});
std.debug.print("new_child == \n\t{*}\n", .{new_child});
// try std.testing.expect(&child == new_child);
std.debug.print("child memory == \n\t{any}\n", .{std.mem.asBytes(&child)});
std.debug.print("new_child memory == \n\t{any}\n", .{std.mem.asBytes(new_child)});
std.debug.print("child.number == \n\t{d}\n", .{child.number});
std.debug.print("new_child.number == \n\t{d}\n", .{new_child.number});
try std.testing.expect(child.number == new_child.number);
}
代码简要描述
由于 因此下面的 疑问按照我的理解,既然是副本,那么 测试输出: test
└─ run test 0/1 passed, 1 failed
error: 'main.test.指针' failed: self.number == 114514
self.number == 114514
self.number == 114514
&child ==
main.test.指针.Child@f7299ff0d8
new_child ==
main.test.指针.Child@f7299ff078
child memory ==
{ 82, 191, 1, 0, 0, 0, 0, 0 }
new_child memory ==
{ 240, 34, 186, 146, 247, 127, 0, 0 }
child.number ==
114514
new_child.number ==
140701295321840
D:\Complier\Zig\zig\lib\std\testing.zig:580:14: 0x7ff792ba102f in expect (test.exe.obj)
if (!ok) return error.TestUnexpectedResult;
^
D:\Application Projects\CLion\Zig\Tetris\src\main.zig:283:5: 0x7ff792ba11f8 in test.指针 (test.exe.obj)
try std.testing.expect(child.number == new_child.number);
^
三个 |
Beta Was this translation helpful? Give feedback.
Answered by
w568w
Apr 20, 2025
Replies: 1 comment 4 replies
-
pub fn makeBase(self: Self) Base 这里是传值,但复制后的副本在栈上。当 |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
这段代码里的匿名对象不是在栈上的,这是因为它的所有成员都是 const 的,故它是
comptime
的。你可以粗略理解为:这种事情的发生是因为:
Local Variables: