How to declare local functions in functions?

Is the following way good? Or are there better ways?

fn foo() u32 {
	const x: u32 = 123;
	
	const T = struct {
		fn bar() u32 {
		    return x;
		}
	};
	
	return T.bar();
}
1 Like

Yup, that’s the way to do it at the moment. You can also do

const bar = struct { fn bar() u32 { ...} }.bar;
2 Likes

Also note that you won’t be able to perform closures with this method. In this case you can only access x from inside bar because it’s a const. Zig doesn’t support closures and it’s more generally not considered an idiomatic style.

2 Likes

Is it safe to reference a local const out of its containing function? Such as

fn foo() fn() u32 {
	const x: u32 = 123;
	
	const T = struct {
		fn bar() u32 {
		    return x;
		}
	};
	
	return T.bar;
}

My current understanding is the following bar1 function is not safe, but how about bar2?

fn bar1() *u32 {
    var x: u32 = 1;
    return &x;
}

fn bar2() *const u32 {
    const x: u32 = 1;
    return &x;
}

To be clear, not only is it the way to do it at the moment, there is no plan to ever change it. #1717 is now closed and there is no other related proposal being considered.

3 Likes

Why are closures not a good idiomatic style? I think they make things easier for some things.

I guess there’re at least two kinds of idiomatic Zig closures.

  1. Function with comptime arguments, which is used for type checking, like in std.meta.trait:
  1. Function that ‘closes’ on another function and its arguments, which is used for callbacks, like in std.Thread.Pool.spawn():
1 Like