Files
sx/examples/protocols/0418-protocols-explicit-receiver.sx
agra 66bdc70bf1 test: group examples into per-category folders
Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
2026-06-21 14:41:34 +03:00

48 lines
1.5 KiB
Plaintext

// Protocol methods declare their receiver EXPLICITLY as the first parameter —
// `self: *Self` (or `self: Self`) — matching the `impl` method signature. This
// is required (the old implicit-receiver form is a parse error). The receiver
// annotation is validated then erased, so dispatch and call sites are unchanged:
// a method with N declared extra args is still called with N args.
#import "modules/std.sx";
Size :: struct { w: i32; h: i32; }
// `self: *Self` receiver; one no-arg method and one with extra args.
Measurable :: protocol #inline {
measure :: (self: *Self) -> Size;
scaled :: (self: *Self, factor: i32) -> Size;
}
// `self: Self` (by-value) receiver is also accepted.
Named :: protocol {
name :: (self: Self) -> string;
}
Widget :: struct { base: i32; }
impl Measurable for Widget {
measure :: (self: *Widget) -> Size { return Size.{ w = self.base, h = self.base * 2 }; }
scaled :: (self: *Widget, factor: i32) -> Size {
return Size.{ w = self.base * factor, h = self.base * 2 * factor };
}
}
impl Named for Widget {
name :: (self: Widget) -> string { return "widget"; }
}
main :: () -> i32 {
w : Widget = .{ base = 5 };
p : *Widget = @w;
m : Measurable = xx p;
s := m.measure(); // 0 extra args
s2 := m.scaled(3); // 1 extra arg
print("measure={}x{}\n", s.w, s.h); // 5x10
print("scaled={}x{}\n", s2.w, s2.h); // 15x30
n : Named = xx p;
print("name={}\n", n.name()); // widget
return 0;
}