0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zig で Closure

Last updated at Posted at 2024-12-04

はじめに

こんにちは。最近 Zig に嵌ってます。
Zig でも無名関数っぽいものはできますが、クロージャ(Closure)はないようなので、研究してみました。
動作を確認した Zig のバージョンは 0.14.0 です。

ソース

const std = @import("std");

fn foo(x: i32) fn (y: i32) i32 {
    return struct {
        var _x: i32 = x;
        pub fn closure(y: i32) i32 {
            _x *= y;
            return _x;
        }
    }.closure;
}

pub fn main() void {
    {
        const f = foo(2);
        std.debug.print("{d}, {d}, {d}\n", .{f(4), f(2), f(10)});
    }
    {
        const f = foo(3);
        std.debug.print("{d}, {d}, {d}\n", .{f(4), f(2), f(10)});
    }
    {
        std.debug.print("{d}\n", .{foo(5)(10)});
    }
}

分かったこと

キャプチャー対象となる変数(ここでは x)をどこに保存するかが問題となりますが、ヒープに保存するのが本手であると思います。
しかし、ヒープを使うとガベージコレクションなどを実装しない限り後始末の問題が残りますので、ここでは、コンパイル時に領域が確保されるいわゆる static (≒ global)にキャプチャーした変数を保存しています。
そのため、複数の Closure を同時に使用した場合の動作に注意が必要となりますので、これでも Closure といえるかどうかは微妙なところです。

キャプチャー対象となる変数がヒープ上にある場合はいずれにせよ後始末が必要ですから、アリーナなどを使ってまとめてヒープ管理するようなものであればできそうではあります。

最後に

Zig は初心者ですので間違いがあったら指摘していただけると大変ありがたいです。
それではみなさん楽しい Zig ライフを。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?