const std = @import("std");
const Animal = struct {
talkFn: *const fn (ptr: *Animal) void,
pub fn talk(self: *Animal) void {
self.talkFn(self);
}
};
const Cat = struct {
anger_level: usize,
parent: Animal,
pub fn init(anger_level: usize) Cat {
const impl = struct {
pub fn talk(ptr: *Animal) void {
const self: *Cat = @fieldParentPtr("parent", ptr);
self.talk();
}
};
return .{
.anger_level = anger_level,
.parent = .{ .talkFn = impl.talk },
};
}
pub fn talk(self: *Cat) void {
std.debug.print("[Cat] Meow! (anger Lv {})\n", .{self.anger_level});
}
};
const Dog = struct {
name: []const u8,
parent: Animal,
pub fn init(name: []const u8) Dog {
const impl = struct {
pub fn talk(ptr: *Animal) void {
const self: *Dog = @fieldParentPtr("parent", ptr);
self.talk();
}
};
return .{
.name = name,
.parent = .{ .talkFn = impl.talk },
};
}
pub fn talk(self: *Dog) void {
std.debug.print("[Dog] I'm a {s}\n", .{self.name});
}
};
pub fn main() !void {
var cat = Cat.init(100);
cat.talk();
var dog = Dog.init("lilly");
dog.talk();
const animals = [_]*Animal{
&cat.parent,
&dog.parent,
};
// const animals = [_]*Animal{
// @constCast(&Cat.init(100).parent),
// @constCast(&Dog.init("lilly").parent),
// };
for (animals) |a| {
a.talk();
}
}
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme