# Function as struct field

**URL:** <https://ziggit.dev/t/function-as-struct-field/3431>\
**Category:** Help\
**Tags:** language\
**Created:** [March 2, 2024, 1:29pm UTC](https://ziggit.dev/t/function-as-struct-field/3431 "2024-03-02T13:29:32Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![pjfichet](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/a5b964/32.png) [@pjfichet](https://ziggit.dev/u/pjfichet)\
**Post date:** [March 2, 2024, 1:29pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/1 "2024-03-02T13:29:32Z")

</div>

Hello alls !

I’m writing code as a hobby, and learning zig writing little toys. For one of them, I was hoping to have a function as field of a struct. My difficulty is that the function will be unique to each instance of the struct.

I would like to write something like this, but can’t find the correct way to do so:

```zig
const std = @import("std");

const Event = struct {
	state: u8,
	text: []const u8,
	condition: fn(*Event) bool,
};

pub fn main() void {
	const event = Event {
		.state = 1,
		.text = "blah blah",
		.condition = fn (self: *Event) bool {
			if (self.state == 1) {
				return true;
			}
		},
	};
	if (event.condition() == true) {
		std.debug.print("event: {}\n", .{event.text});
	}
}

```

Is there a proper way to express this in Zig 0.11.0 ?

---

<div class="post-metadata">

**Author:** ![dee0xeed](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/3ab097/32.png) [@dee0xeed](https://ziggit.dev/u/dee0xeed)\
**Post date:** [March 2, 2024, 1:34pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/2 "2024-03-02T13:34:17Z")

</div>

You need a function pointer:

```zig
const funcPtr = *const fn(args...) void;
f_ptr: funcPtr = &nameOfAFunc;

```

---

<div class="post-metadata">

**Author:** ![pjfichet](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/a5b964/32.png) [@pjfichet](https://ziggit.dev/u/pjfichet)\
**Post date:** [March 2, 2024, 1:47pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/3 "2024-03-02T13:47:48Z")

</div>

Thank you ! I still can’t find how to express this within a struct…

```zig
const std = @import("std");
 2
 3 const funcPtr = *const fn(*Event) bool;
 4
 5
 6 const Event = struct {
 7 state: u8,
 8 text: []const u8,
 9 condition: funcPtr,
10 };
11
12 fn myCondition(self: *Event) bool {
13 if (self.state == 1) {
14 return true;
15 }
16 return false;
17 }
18
19 pub fn main() void {
20 const event = Event {
21 .state = 1,
22 .text = "blah blah",
23 .condition = &myCondition,
24 };
25 if (event.condition() == true) {
26 std.debug.print("event: {}\n", .{event.text});
27 }
28 }

```

```zig
error: expected 1 argument(s), found 0
 if (event.condition() == true) {

```

---

<div class="post-metadata">

**Author:** ![dee0xeed](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/3ab097/32.png) [@dee0xeed](https://ziggit.dev/u/dee0xeed)\
**Post date:** [March 2, 2024, 2:01pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/4 "2024-03-02T14:01:19Z")

</div>

> [@pjfichet](#):
>
> to express this within a struct

It does not matter whether a function pointer is a filed of a struct or a standalone variable, syntax is the same.

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [March 2, 2024, 2:03pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/5 "2024-03-02T14:03:47Z")

</div>

```zig
const std = @import("std");

const funcPtr = *const fn (*const Event) bool;

const Event = struct {
    state: u8,
    text: []const u8,
    condition: funcPtr,
};

fn myCondition(self: *const Event) bool {
    return (self.state == 1);
}

pub fn main() void {
    const event = Event{
        .state = 1,
        .text = "blah blah",
        .condition = &myCondition,
    };
    if (event.condition(&event)) {
        std.debug.print("event: {s}\n", .{event.text});
    }
}

```

---

<div class="post-metadata">

**Author:** ![pjfichet](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/a5b964/32.png) [@pjfichet](https://ziggit.dev/u/pjfichet)\
**Post date:** [March 2, 2024, 2:07pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/6 "2024-03-02T14:07:54Z")

</div>

Thank you for the answers !

I’m a bit sad I can’t define the function while instanciating the struct, and use the syntactical sugar to call it without argument. But it will do !

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [March 2, 2024, 2:34pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/7 "2024-03-02T14:34:15Z")

</div>

Right now zig does not support anonymous functions - you have to define them “inside” something - struct, union, enum, or root level of a file.

---

<div class="post-metadata">

**Author:** ![dee0xeed](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/3ab097/32.png) [@dee0xeed](https://ziggit.dev/u/dee0xeed)\
**Post date:** [March 2, 2024, 2:37pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/8 "2024-03-02T14:37:10Z")

</div>

My little example, just in case (a sort of dynamic dispatch via virtual method table, with one element in this case):

```zig
const std = @import("std");
const log = std.debug.print;

const methodPtr = *const fn(c: *Class) void;

const Class = struct {
    x: u32,
    m: methodPtr,

    fn callMethod(i: *Class) void {
        i.m(i);
    }
};

pub fn main() void {
    var inst1 = Class{.x = 1, .m = &m1};
    var inst2 = Class{.x = 2, .m = &m2};
    inst1.callMethod();
    inst2.callMethod();
}

fn m1(i: *Class) void {
    log("my x is {}\n", .{i.x});
    log("I can do this\n", .{});
}

fn m2(i: *Class) void {
    log("my x is {}\n", .{i.x});
    log("I can do that\n", .{});
}

```

Also, when I see the words “state” and “event” close to each other,  
I immediately start to guess that this is about “event driven state machines” or so.  
EDSM, as I call it, is a design methodology which I advocate here and there 🙂  
If you are interested you can take a look at my GitHub repos with `edsm` in names (nick is the same as on this forum, dee0xeed). There are various versions of the engine and, If I remember right, the most recent was [here](https://github.com/dee0xeed/xjiss/tree/main/xjiss2/src/engine).

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [March 2, 2024, 3:45pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/9 "2024-03-02T15:45:18Z")

</div>

Just a little style note here: In all these examples, `funcPtr` and `methodPtr` are types so they should be PascalCase: `FuncPtr` and `MethodPtr`.

Also, since they’re used only once, why not just use the type directly in the struct. field def:

```zig
m: *const fn(c: *Class) void,

```

---

<div class="post-metadata">

**Author:** ![dee0xeed](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/3ab097/32.png) [@dee0xeed](https://ziggit.dev/u/dee0xeed)\
**Post date:** [March 2, 2024, 5:03pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/10 "2024-03-02T17:03:04Z")

</div>

> [@dude\_the\_builder](#):
>
> are types so they should be PascalCase: `FuncPtr` and `MethodPtr`

TBH, I do not know why I used camelCase for them, I depicted it from some code I wrote before (probably at that time I did not think right and was not realizing these should be in PascalCase).

And, BTW, here is small excerpt from `/opt/zig-0.11/lib/std$ grep -rI "= \*const fn"`:

```zig
os/plan9.zig: pub const handler_fn = *const fn (c_int) callconv(.C) void;
os/plan9.zig: pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
os/windows/ws2_32.zig:pub const LPCONDITIONPROC = *const fn (

```

😁

> [@dude\_the\_builder](#):
>
> why not just use the type directly in the struct. field def

Because at a later time they may be used more than once, why not declare the type in advance?

---

<div class="post-metadata">

**Author:** ![pjfichet](https://ziggit.dev/letter_avatar_proxy/v4/letter/p/a5b964/32.png) [@pjfichet](https://ziggit.dev/u/pjfichet)\
**Post date:** [March 2, 2024, 6:42pm UTC](https://ziggit.dev/t/function-as-struct-field/3431/11 "2024-03-02T18:42:35Z")

</div>

Thank you all for the detailed explanations.

@dee0xeed : I will study event driven state machines and your implementation, as indeed, it might be a solution to do what I’m trying to do.
