🍮

[小ネタ] Zig で匿名関数

2023/04/15に公開

匿名関数は非サポート?

Zig のドキュメントに匿名関数について記載がないので調べてみたところ、どうやら匿名関数はサポートしていないようす。過去に提案はあったようですが採用はされていない様子。
functions inside functions (closures)
I searched for anonymous function (and lambda function) in the docs and didn't find it

上記 Issue を読むと匿名構造体経由で関数を変数にセットすることができるので、ほとんど匿名関数と同じことができそうです。

main.zig
const std = @import("std");

pub fn main() void {
    // NG
    // const add2 = fn(x: isize) isize {
    // return x+2;
    // };

    // 匿名構造体で関数を定義、その関数を変数 add にセット
    const add2 = struct {
        pub fn f(x: isize) isize {
            return x + 2;
        }
    }.f;

    std.debug.print("add2(3)={d}\n", .{add2(3)});

    // const y = 100; でも OK
    comptime var y = 100;
    const addY = struct {
        pub fn f(x: isize) isize {
            // y は comptime な値でないとコンパイルエラーになる
            return x + y;
        }
    }.f;

    std.debug.print("addY(3)={d}\n", .{addY(3)});

    std.debug.print("add1000(add2)(3)={d}\n", .{add1000(add2)(3)});
    std.debug.print("add1000(addY)(3)={d}\n", .{add1000(addY)(3)});
}

fn add1000(comptime f: fn (x: isize) isize) fn (isize) isize {
    return struct {
        pub fn add(x: isize) isize {
            return f(x) + 1000;
        }
    }.add;
}

$ zig run main.zig

add2(3)=5
addY(3)=103
add1000(add2)(3)=1005
add1000(addY)(3)=1103

Discussion