# How to extend a type in Zig

**URL:** <https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136>\
**Category:** Help\
**Tags:** language, type-system\
**Created:** [July 22, 2025, 9:22pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136 "2025-07-22T21:22:23Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![giluis](https://ziggit.dev/user_avatar/ziggit.dev/giluis/32/5886_2.png) [@giluis](https://ziggit.dev/u/giluis)\
**Post date:** [July 22, 2025, 9:22pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/1 "2025-07-22T21:22:23Z")

</div>

Hello 🙂  
I need to create N types that share a lot of functionality. Say they have 12 member functions each, 2 of which are specific to each type (in function signature and implementation), and the other 10 are exactly the same for all types (in function signature and implementation).

I wanted to abstract out the common behavior so I wouldn’t have to rewrite the same functions over and over again.  
What I did was

```zig
fn MyLargeType() type {

   return struct {
       fn one_of_many() void {...}
       fn another_one_of_many() void {...}
      // ... many more functions
   }
}

fn SmallType1() {
     return struct {
           usingnamespace MyLargeType;
           fn specificFunction1() {...}

           // plus a couple other functions specific to this type
     }
}

// same for SmallType2... SmallTypeN

```

Obviously this won’t work anymore since usingnamspace has been removed from the language,  
In Zig 0.15 hwo may I achieve this sort of behaviour? I’m open to unusual solutions.

Only thing that comes to mind (besides code generation, which I don’t really want to do unless it’s absolutely the only way) is having a MyLargeType field in all of my types and forwarding its methods. t/This saves me some LoC for the implementation itself, but I still have to repeatedly write declarations and the forwarding part myself by hand.  
For many dozens of methods, and N types, that’s a whole lot of manual work.

Please help me, thank you !

---

<div class="post-metadata">

**Author:** ![pachde](https://ziggit.dev/user_avatar/ziggit.dev/pachde/32/2485_2.png) [@pachde](https://ziggit.dev/u/pachde)\
**Post date:** [July 22, 2025, 9:32pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/2 "2025-07-22T21:32:45Z")

</div>

Some will argue that instead of attempting to reinvent OOP inheritance in Zig, you should model your app differently through composition.

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [July 23, 2025, 12:53am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/3 "2025-07-23T00:53:09Z")

</div>

> [@giluis](#):
>
> Only thing that comes to mind (besides code generation, which I don’t really want to do unless it’s absolutely the only way) is having a MyLargeType field in all of my types and forwarding its methods. t/This saves me some LoC for the implementation itself, but I still have to repeatedly write declarations and the forwarding part myself by hand.

that is the recommended solution. Is there any reason you need to write wrappers around the base type’s functions instead of just doing `small_type.base.one_of_many()`?

---

<div class="post-metadata">

**Author:** ![Flaminator](https://ziggit.dev/user_avatar/ziggit.dev/flaminator/32/5894_2.png) [@Flaminator](https://ziggit.dev/u/Flaminator)\
**Post date:** [July 23, 2025, 9:45pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/4 "2025-07-23T21:45:13Z")

</div>

It was an intentional decision to remove the mixin part from the language without any serious alternative as it’s not the prefered way to write zig code.  
I myself got hit by this hard as there were only a few files in my projects that didn’t use this feature.

I believe there are like a 3 or 4 things you can possibly do:

1. What I myself ended up doing is something like the following:

```zig
const test1 = struct 
{
    comptime { @import("mixin").implements(test1, .{Interface}); }
    pub const func2 = Interface(test1).func2;
    pub const func3 = Interface(test1).func3;
    pub const func1 = Interface(test1).func1;

    value: i32
};

fn Interface(comptime record: type) type
{
    return struct
    {
        pub fn func1(r: record) i32 {return r.value;}
        pub fn func2() i32 {return 2;}
        pub fn func3(r: *record, value: i32) i32 {r.value += value; return r.value;}
    };
}

```

The `mixin.implements` import does some checking to make sure it points to the correct implementation. You do end having to duplicate a lot of extra lines in your code that the `usingnamespace` used to do for you. But atleast the behaviour you get is the same as with `usingnamespace`.
2. Abandon what you are doing and start over in a new way.
3. Basically the same as option 1. but without the strict checking.

Some people prefer to do the following or prefer a more C like way of doing things:

1. Using composition/Exposing implementation details by adding a member to your structs like proposed by @pachde and @vulpesx
2. C style object orientated programming using runtime shenanigans(I wouldn’t use this but there are people who are fan of this).

---

<div class="post-metadata">

**Author:** ![andrewrk](https://ziggit.dev/user_avatar/ziggit.dev/andrewrk/32/7011_2.png) [@andrewrk](https://ziggit.dev/u/andrewrk)\
**Post date:** [July 23, 2025, 10:23pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/5 "2025-07-23T22:23:11Z")

</div>

use composition instead

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [July 23, 2025, 11:30pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/6 "2025-07-23T23:30:40Z")

</div>

I’ve found that it’s often more manageable to simply stick a `switch()` into each of the “polymorphic” functions. Modern editors handling code folding quite well. Massive switch statements really don’t cause practical issues.

Conceptually, you’d only have one parameterized type:

```zig
fn MyType(comptime options: struct {
    param1: bool = false,
    param2: bool = false,
    param3: usize = 0,
    // ...
}) type {
    return struct {
        // ...
    };
};

```

Individual methods within the returned struct would then simply react to the parameters given (possibly using `switch`). When they don’t, then the compiler will automatically collapse them to the same function.

---

<div class="post-metadata">

**Author:** ![floooh](https://ziggit.dev/user_avatar/ziggit.dev/floooh/32/2989_2.png) [@floooh](https://ziggit.dev/u/floooh)\
**Post date:** [July 24, 2025, 9:45am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/7 "2025-07-24T09:45:40Z")

</div>

What I do in C (and also would do in Zig) is nested structs (e.g. what’s commonly called composition), e.g.:

```c
// all resource objects have a slot:
typedef struct {
    uint32_t id;
    uint32_t uninit_count;
    sg_resource_state state;
} _sg_slot_t;

// all common properties of a buffer resource:
typedef struct {
    // ...
} _sg_buffer_common_t;

// the 3D API specific parts of a buffer resource (here: D3D11):
typedef struct {
    // ...
} _sg_d3d11_buffer_t;

// and finally the actual 'composed' buffer for when the D3D11 backend is active:
typedef struct {
    sg_slot_t slot;
    sg_buffer_common_t cmn;
    sg_d3d11_buffer_t d3d11;
} _sg_buffer_t;

```

…this is similar to inheritance (Slot =\> BufferBase =\> D3D11Buffer =\> Buffer), but more flexible since you can ‘compose’ the different parts more freely (also google for ‘composition over inheritance’).

---

<div class="post-metadata">

**Author:** ![giluis](https://ziggit.dev/user_avatar/ziggit.dev/giluis/32/5886_2.png) [@giluis](https://ziggit.dev/u/giluis)\
**Post date:** [July 24, 2025, 10:17am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/8 "2025-07-24T10:17:00Z")

</div>

How can I achieve what I want (avoiding code repetition) with composition in this case? Can you give an example of what you mean?

---

<div class="post-metadata">

**Author:** ![floooh](https://ziggit.dev/user_avatar/ziggit.dev/floooh/32/2989_2.png) [@floooh](https://ziggit.dev/u/floooh)\
**Post date:** [July 24, 2025, 10:35am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/9 "2025-07-24T10:35:01Z")

</div>

Like this basically:

> **[Compiler Explorer - Zig](https://www.godbolt.org/z/Eonqrv3vz)**
>
> const print = @import("std").debug.print;
> 
> fn MyLargeType() type {
> return struct {
> const Self = @This();
> fn one\_of\_many(self: \*const Self) void {
> \_ = self;
> print("one\_of\_many called\\n", .{});
> }
> fn...

…e.g. instead of

```ts
    bla.one_of_many();

```

…it would be:

```ts
    bla.cmn.one_of_many();

```

(it’s essentially the same thing you propose, just minus the `usingnamespace` magic)

---

<div class="post-metadata">

**Author:** ![Flaminator](https://ziggit.dev/user_avatar/ziggit.dev/flaminator/32/5894_2.png) [@Flaminator](https://ziggit.dev/u/Flaminator)\
**Post date:** [July 24, 2025, 11:42am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/10 "2025-07-24T11:42:48Z")

</div>

This of course only works when the functions being called don’t use anything from `SmallType1`.  
Things will get hairy when you do need to call something from the parent. You either need to pass in the parent as parameter to the function making it possible to pass in the wrong thing or you’ll have to do some very dirty C style/linux kernel object orientated programming.

---

<div class="post-metadata">

**Author:** ![floooh](https://ziggit.dev/user_avatar/ziggit.dev/floooh/32/2989_2.png) [@floooh](https://ziggit.dev/u/floooh)\
**Post date:** [July 24, 2025, 11:48am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/11 "2025-07-24T11:48:38Z")

</div>

> [@Flaminator](#):
>
> This of course only works when the functions being called don’t use anything from `SmallType1`.

True, but that would be similar to a parent class trying to access items of a subclass. The more common scenario of the subclass accessing the parent class works (via `self.cmn`).

---

<div class="post-metadata">

**Author:** ![cztomsik](https://ziggit.dev/user_avatar/ziggit.dev/cztomsik/32/3032_2.png) [@cztomsik](https://ziggit.dev/u/cztomsik)\
**Post date:** [July 24, 2025, 1:58pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/12 "2025-07-24T13:58:50Z")

</div>

you can use @fieldParentPtr

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [July 25, 2025, 12:29am UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/13 "2025-07-25T00:29:27Z")

</div>

should be avoided as it is illegal behaviour to use that when its not in the specified field of the specified type

---

<div class="post-metadata">

**Author:** ![Dave](https://ziggit.dev/letter_avatar_proxy/v4/letter/d/ee7513/32.png) [@Dave](https://ziggit.dev/u/Dave)\
**Post date:** [July 28, 2025, 2:17pm UTC](https://ziggit.dev/t/how-to-extend-a-type-in-zig/11136/14 "2025-07-28T14:17:59Z")

</div>

> [@giluis](#):
>
> ```zig
> fn MyLargeType() type {
> 
> return struct {
> fn one_of_many() void {...}
> fn another_one_of_many() void {...}
> // ... many more functions
> }
> }
> 
> fn SmallType1() {
> return struct {
> // usingnamespace MyLargeType;
> const MLT = MyLargeType();
> const one_of_many = MLT.one_of_many;
> const another_one_of_many = MLT.another_one_of_many;
> // etc.
> fn specificFunction1() {...}
> 
> // plus a couple other functions specific to this type
> }
> }
> 
> ```

While this may seem tedious, you only need to do it once, and you can copy/paste into all the other SmallTypes.
