Struct¶
A struct is a plain bundle of fields — state without behavior. Where a class pairs data with operations, a struct is just the data. The same minimal Color record across languages:
const std = @import("std");
const Color = struct {
r: u8,
g: u8,
b: u8,
};
pub fn main() !void {
const c = Color{ .r = 255, .g = 128, .b = 0 };
try std.io.getStdOut().writer().print("#{x:0>2}{x:0>2}{x:0>2}\n", .{ c.r, c.g, c.b });
}
package main
import "fmt"
type Color struct {
R, G, B uint8
}
func main() {
c := Color{R: 255, G: 128, B: 0}
fmt.Printf("#%02x%02x%02x\n", c.R, c.G, c.B)
}
from dataclasses import dataclass
@dataclass(frozen=True)
class Color:
r: int
g: int
b: int
c = Color(255, 128, 0)
print(f"#{c.r:02x}{c.g:02x}{c.b:02x}")
struct Color {
r: u8,
g: u8,
b: u8,
}
fn main() {
let c = Color { r: 255, g: 128, b: 0 };
println!("#{:02x}{:02x}{:02x}", c.r, c.g, c.b);
}
#include <stdio.h>
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} Color;
int main(void) {
Color c = {.r = 255, .g = 128, .b = 0};
printf("#%02x%02x%02x\n", c.r, c.g, c.b);
}
#include <cstdio>
struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
};
int main() {
Color c{255, 128, 0};
std::printf("#%02x%02x%02x\n", c.r, c.g, c.b);
}
using System;
public readonly record struct Color(byte R, byte G, byte B);
var c = new Color(255, 128, 0);
Console.WriteLine($"#{c.R:x2}{c.G:x2}{c.B:x2}");
interface Color {
r: number;
g: number;
b: number;
}
const c: Color = { r: 255, g: 128, b: 0 };
console.log(`#${c.r.toString(16).padStart(2, "0")}${c.g.toString(16).padStart(2, "0")}${c.b.toString(16).padStart(2, "0")}`);
const c = { r: 255, g: 128, b: 0 };
const hex = (n) => n.toString(16).padStart(2, "0");
console.log(`#${hex(c.r)}${hex(c.g)}${hex(c.b)}`);
data class Color(val r: Int, val g: Int, val b: Int)
fun main() {
val c = Color(255, 128, 0)
println("#%02x%02x%02x".format(c.r, c.g, c.b))
}
final case class Color(r: Int, g: Int, b: Int)
@main def run(): Unit =
val c = Color(255, 128, 0)
println(f"#${c.r}%02x${c.g}%02x${c.b}%02x")
public record Color(int r, int g, int b) {
public static void main(String[] args) {
Color c = new Color(255, 128, 0);
System.out.printf("#%02x%02x%02x%n", c.r(), c.g(), c.b());
}
}
#!/usr/bin/env bash
# Bash has no structs. We approximate one with an associative array
# whose keys are the field names.
declare -A c=([r]=255 [g]=128 [b]=0)
printf "#%02x%02x%02x\n" "${c[r]}" "${c[g]}" "${c[b]}"
Update¶
Structs are often treated as immutable — produce a new value with one field changed rather than mutating in place:
const dimmed = Color{ .r = c.r / 2, .g = c.g, .b = c.b };
dimmed := c
dimmed.R = c.R / 2
from dataclasses import replace
dimmed = replace(c, r=c.r // 2)
let dimmed = Color { r: c.r / 2, ..c };
Color dimmed = c;
dimmed.r = c.r / 2;
Color dimmed = c;
dimmed.r = c.r / 2;
var dimmed = c with { R = (byte)(c.R / 2) };
const dimmed: Color = { ...c, r: c.r / 2 };
const dimmed = { ...c, r: c.r / 2 };
val dimmed = c.copy(r = c.r / 2)
val dimmed = c.copy(r = c.r / 2)
Color dimmed = new Color(c.r() / 2, c.g(), c.b());
declare -A dimmed
for k in r g b; do dimmed[$k]="${c[$k]}"; done
dimmed[r]=$(( c[r] / 2 ))