# Anonymous Structs

### Anonymous Structs

An anonymous struct is a struct type without a name.

You have already seen named structs:

```zig
const Point = struct {
    x: i32,
    y: i32,
};
```

Here, the struct type has a name: `Point`.

An anonymous struct does not have a declared name:

```zig
const p = .{
    .x = 10,
    .y = 20,
};
```

This creates a value with two fields, `x` and `y`, but we did not define a separate `Point` type.

The type exists, but it is inferred from the literal.

#### Anonymous Struct Literals

The basic anonymous struct literal looks like this:

```zig
.{
    .field_name = value,
    .field_name = value,
}
```

Example:

```zig
const user = .{
    .id = 1,
    .name = "Ada",
    .active = true,
};
```

This value has three fields:

```text
id
name
active
```

You can access them with dot syntax:

```zig
const name = user.name;
const active = user.active;
```

This works like a normal struct value.

#### Named Struct vs Anonymous Struct

A named struct is better when the data has a clear meaning in your program.

```zig
const User = struct {
    id: u64,
    name: []const u8,
    active: bool,
};
```

Then you create values like this:

```zig
const user = User{
    .id = 1,
    .name = "Ada",
    .active = true,
};
```

An anonymous struct is better for small local values:

```zig
const user = .{
    .id = 1,
    .name = "Ada",
    .active = true,
};
```

The difference is not only style. A named struct gives the type a reusable name. An anonymous struct does not.

Use a named struct when the type appears in function signatures, public APIs, collections, or important program logic.

Use an anonymous struct when the value is short-lived and local.

#### Anonymous Structs in Formatting

You often see anonymous structs in `std.debug.print`.

```zig
std.debug.print("x = {}, y = {}\n", .{ 10, 20 });
```

The second argument is an anonymous tuple-like struct:

```zig
.{ 10, 20 }
```

It has values but no field names.

This is how Zig passes formatting arguments. The format string has two `{}` placeholders, and the anonymous struct contains two values.

```zig
std.debug.print("{} + {} = {}\n", .{ 2, 3, 5 });
```

Output:

```text
2 + 3 = 5
```

This is one of the most common places beginners first see anonymous structs.

#### Tuple-Like Anonymous Structs

Anonymous structs can be written without field names:

```zig
const pair = .{ 10, "hello" };
```

This is a tuple-like anonymous struct.

The fields are indexed by position. You can access them with numeric field names:

```zig
const number = pair[0];
const text = pair[1];
```

In Zig, tuple-like structs are useful for temporary groups of values, especially when passing arguments to formatting functions.

But for most program data, prefer named fields:

```zig
const pair = .{
    .count = 10,
    .message = "hello",
};
```

This is easier to read:

```zig
pair.count
pair.message
```

Field names explain meaning. Positions require the reader to remember meaning.

#### Anonymous Structs with Field Names

You can use named fields without declaring a named type:

```zig
const config = .{
    .host = "127.0.0.1",
    .port = 8080,
    .debug = false,
};
```

Then:

```zig
std.debug.print("{}:{}\n", .{ config.host, config.port });
```

This is useful when the value is only needed in one small area.

For example:

```zig
const server = .{
    .host = "127.0.0.1",
    .port = 8080,
};

std.debug.print("server = {s}:{}\n", .{
    server.host,
    server.port,
});
```

The anonymous struct keeps the code compact without creating a new top-level type.

#### Anonymous Structs and Type Inference

This expression:

```zig
const p = .{
    .x = 10,
    .y = 20,
};
```

uses type inference.

Zig sees the fields and values, then creates a matching anonymous struct type.

The field `x` gets the type of `10`.

The field `y` gets the type of `20`.

Sometimes you want a specific named type. In that case, write the type explicitly:

```zig
const Point = struct {
    x: i32,
    y: i32,
};

const p = Point{
    .x = 10,
    .y = 20,
};
```

This makes `p` a `Point`.

#### Coercing Anonymous Structs to Named Structs

An anonymous struct literal can often be used where a named struct is expected.

```zig
const Point = struct {
    x: i32,
    y: i32,
};

fn printPoint(p: Point) void {
    std.debug.print("({}, {})\n", .{ p.x, p.y });
}

pub fn main() void {
    printPoint(.{
        .x = 10,
        .y = 20,
    });
}
```

The function expects a `Point`.

The call passes an anonymous struct literal with the right fields.

Zig can coerce it into `Point`.

This is common and useful. You do not always need to write `Point{ ... }` if the expected type is already clear from context.

You can also write it explicitly:

```zig
printPoint(Point{
    .x = 10,
    .y = 20,
});
```

Both forms are valid when the context is clear.

#### Anonymous Structs in Function Calls

Anonymous struct literals are useful for options parameters.

Suppose a function accepts a config struct:

```zig
const Options = struct {
    verbose: bool = false,
    retries: u8 = 3,
};

fn run(options: Options) void {
    _ = options;
}
```

You can call it like this:

```zig
run(.{});
```

This uses all defaults.

You can override one field:

```zig
run(.{
    .verbose = true,
});
```

The expected type is `Options`, so Zig knows how to interpret the literal.

This style keeps call sites short while preserving type checking.

#### Anonymous Structs Are Still Strongly Typed

Anonymous does not mean dynamic.

This is still compile-time checked:

```zig
const value = .{
    .name = "Ada",
    .age = 36,
};
```

The fields are known at compile time.

This works:

```zig
const age = value.age;
```

This does not:

```zig
const email = value.email;
```

There is no `email` field, so Zig rejects the program.

Anonymous structs are not maps. They are not dictionaries. They are fixed compile-time types.

#### Anonymous Structs Are Not Good Public APIs

Avoid anonymous structs in public interfaces when the data has an important meaning.

This is harder to understand:

```zig
fn createUser(data: anytype) void {
    _ = data.name;
    _ = data.email;
}
```

The caller has to guess what shape `data` should have.

This is clearer:

```zig
const CreateUserOptions = struct {
    name: []const u8,
    email: []const u8,
    active: bool = true,
};

fn createUser(options: CreateUserOptions) void {
    _ = options.name;
    _ = options.email;
}
```

Now the type documents the required fields.

Anonymous structs are best for local convenience, not for hiding important structure.

#### Anonymous Structs as Namespaces

You can also create anonymous structs for grouping declarations, though named structs are usually clearer.

```zig
const Math = struct {
    pub fn add(a: i32, b: i32) i32 {
        return a + b;
    }

    pub fn sub(a: i32, b: i32) i32 {
        return a - b;
    }
};
```

Technically, the `struct { ... }` type is anonymous. It gets the name `Math` because we assign it to a constant.

This pattern is common in Zig. Many named types are written this way:

```zig
const Name = struct {
    // fields and declarations
};
```

The struct expression itself is anonymous. The constant gives it a useful name.

#### A Practical Example

Here is a small program that uses both named and anonymous structs:

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

const Server = struct {
    host: []const u8,
    port: u16,

    pub fn print(self: Server) void {
        std.debug.print("server = {s}:{}\n", .{
            self.host,
            self.port,
        });
    }
};

pub fn main() void {
    const local = Server{
        .host = "127.0.0.1",
        .port = 8080,
    };

    local.print();

    const temporary = .{
        .host = "example.com",
        .port = 443,
    };

    std.debug.print("temporary = {s}:{}\n", .{
        temporary.host,
        temporary.port,
    });
}
```

`Server` is a named struct because it represents a real concept in the program.

`temporary` is anonymous because it is only used once.

#### The Main Idea

Anonymous structs let you group values without creating a named type.

```zig
const p = .{
    .x = 10,
    .y = 20,
};
```

They are useful for formatting arguments, short local values, and option literals where the expected type is already clear.

Use named structs for important concepts:

```zig
const Point = struct {
    x: i32,
    y: i32,
};
```

Use anonymous structs for small temporary groups:

```zig
.{ 10, 20 }
```

The rule is simple: if the shape matters across your program, give it a name.

