Token导航 LogoToken导航TokenDH.com
AI 工具需要联网github未标认证来源可访问clear审计通过

axiom-ownership-conventions公理所有权约定

Agent Skill

axiom-ownership-conventions 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

3,930

周安装

159

GitHub Stars

873

下载量

1,234
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:axiom-ownership-conventions(公理所有权约定)
来源仓库:https://github.com/charleswiltgen/axiom
仓库路径:skills/axiom-ownership-conventions
安装命令:
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-ownership-conventions
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-ownership-conventions

简介

定义 Swift 参数所有权修饰符(borrowing & consuming)的使用规范与性能优化策略。

  • 适用于大型值类型只读传递、noncopyable 类型支持及 ARC 开销降低场景。
  • 帮助开发者区分何时需要显式所有权控制,何时可依赖编译器优化。
  • 使用前应通过 Instruments 验证拷贝行为是否真实影响性能瓶颈。
  • 注意过度使用可能降低代码可读性,应在 profiling 数据支持下谨慎应用。

SKILL.md

borrowing & consuming — Parameter Ownership

Explicit ownership modifiers for performance optimization and noncopyable type support.

When to Use

Use when:

  • Large value types being passed read-only (avoid copies)
  • Working with noncopyable types (~Copyable)
  • Reducing ARC retain/release traffic
  • Factory methods that consume builder objects
  • Performance-critical code where copies show in profiling

Don't use when:

  • Simple types (Int, Bool, small structs)
  • Compiler optimization is sufficient (most cases)
  • Readability matters more than micro-optimization
  • You're not certain about the performance impact

Quick Reference

ModifierOwnershipCopiesUse Case
(default)Compiler choosesImplicitMost cases
borrowingCaller keepsExplicit copy onlyRead-only, large types
consumingCaller transfersNone neededFinal use, factories
inoutCaller keeps, mutableNoneModify in place

Default Behavior by Context

ContextDefaultReason
Function parametersborrowingMost params are read-only
Initializer parametersconsumingUsually stored in properties
Property settersconsumingValue is stored
Method selfborrowingMethods read self

Patterns

Pattern 1: Read-Only Large Struct

struct LargeBuffer {
    var data: [UInt8]  // Could be megabytes
}

// ❌ Default may copy
func process(_ buffer: LargeBuffer) -> Int {
    buffer.data.count
}

// ✅ Explicit borrow — no copy
func process(_ buffer: borrowing LargeBuffer) -> Int {
    buffer.data.count
}

Pattern 2: Consuming Factory

struct Builder {
    var config: Configuration

    // Consumes self — builder invalid after call
    consuming func build() -> Product {
        Product(config: config)
    }
}

let builder = Builder(config: .default)
let product = builder.build()
// builder is now invalid — compiler error if used

Pattern 3: Explicit Copy in Borrowing

With borrowing, copies must be explicit:

func store(_ value: borrowing LargeValue) {
    // ❌ Error: Cannot implicitly copy borrowing parameter
    self.cached = value

    // ✅ Explicit copy
    self.cached = copy value
}

Pattern 4: Consume Operator

Transfer ownership explicitly:

let data = loadLargeData()
process(consume data)
// data is now invalid — compiler prevents use

Pattern 5: Noncopyable Type

For ~Copyable types, ownership modifiers are required:

struct FileHandle: ~Copyable {
    private let fd: Int32

    init(path: String) throws {
        fd = open(path, O_RDONLY)
        guard fd >= 0 else { throw POSIXError.errno }
    }

    borrowing func read(count: Int) -> Data {
        // Read without consuming handle
        var buffer = [UInt8](repeating: 0, count: count)
        _ = Darwin.read(fd, &buffer, count)
        return Data(buffer)
    }

    consuming func close() {
        Darwin.close(fd)
        // Handle consumed — can't use after close()
    }

    deinit {
        Darwin.close(fd)
    }
}

// Usage
let file = try FileHandle(path: "/tmp/data.txt")
let data = file.read(count: 1024)  // borrowing
file.close()  // consuming — file invalidated

Pattern 6: Reducing ARC Traffic

class ExpensiveObject { /* ... */ }

// ❌ Default: May retain/release
func inspect(_ obj: ExpensiveObject) -> String {
    obj.description
}

// ✅ Borrowing: No ARC traffic
func inspect(_ obj: borrowing ExpensiveObject) -> String {
    obj.description
}

Pattern 7: Consuming Method on Self

struct Transaction {
    var amount: Decimal
    var recipient: String

    // After commit, transaction is consumed
    consuming func commit() async throws {
        try await sendToServer(self)
        // self consumed — can't modify or reuse
    }
}

Common Mistakes

Mistake 1: Over-Optimizing Small Types

// ❌ Unnecessary — Int is trivially copyable
func add(_ a: borrowing Int, _ b: borrowing Int) -> Int {
    a + b
}

// ✅ Let compiler optimize
func add(_ a: Int, _ b: Int) -> Int {
    a + b
}

Mistake 2: Forgetting Explicit Copy

func cache(_ value: borrowing LargeValue) {
    // ❌ Compile error
    self.values.append(value)

    // ✅ Explicit copy required
    self.values.append(copy value)
}

Mistake 3: Consuming When Borrowing Suffices

// ❌ Consumes unnecessarily — caller loses access
func validate(_ data: consuming Data) -> Bool {
    data.count > 0
}

// ✅ Borrow for read-only
func validate(_ data: borrowing Data) -> Bool {
    data.count > 0
}

~Copyable Limitations

Know the constraints before adopting ~Copyable:

LimitationImpactWorkaround
Can't store in Array, Dictionary, SetCollections require CopyableUse Optional<T> wrapper or manage manually
Can't use with most generics<T> implicitly means <T: Copyable>Use <T: ~Copyable> (requires library support)
Protocol conformance restrictedMost protocols require CopyableUse ~Copyable protocol definitions
Can't capture in closures by defaultClosures copy captured valuesUse borrowing closure parameters
No existential supportany ~Copyable doesn't workUse generics instead

Common compiler errors when adopting ownership modifiers:

// Error: "Cannot implicitly copy a borrowing parameter"
// Fix: Add explicit `copy` or change to consuming
func store(_ v: borrowing LargeValue) {
    self.cached = copy v  // ✅ Explicit copy
}

// Error: "Noncopyable type cannot be used with generic"
// Fix: Constrain generic to ~Copyable
func use<T: ~Copyable>(_ value: borrowing T) { }  // ✅

// Error: "Cannot consume a borrowing parameter"
// Fix: Change to consuming if you need ownership transfer
func takeOwnership(_ v: consuming FileHandle) { }  // ✅

// Error: "Missing 'consuming' or 'borrowing' modifier"
// Fix: ~Copyable types require explicit ownership on all methods
struct Token: ~Copyable {
    borrowing func peek() -> String { ... }   // ✅ Explicit
    consuming func redeem() { ... }           // ✅ Explicit
}

When NOT to use ~Copyable:

  • If you need collection storage (arrays, dictionaries)
  • If you need to work with existing generic APIs
  • If the type needs broad protocol conformance
  • Prefer consuming func on regular types as a lighter alternative for "use once" semantics

Performance Considerations

When Ownership Modifiers Help

  • Large structs (arrays, dictionaries, custom value types)
  • High-frequency function calls in tight loops
  • Reference types where ARC traffic is measurable
  • Noncopyable types (required, not optional)

When to Skip

  • Default behavior is almost always optimal
  • Small value types (primitives, small structs)
  • Code where profiling shows no benefit
  • API stability concerns (modifiers affect ABI)

InlineArray

Fixed-size, stack-allocated array using value generics. No heap allocation, no reference counting, no copy-on-write.

Declaration

@frozen struct InlineArray<let count: Int, Element> where Element: ~Copyable

The let count: Int is a value generic — the size is part of the type, checked at compile time. InlineArray<3, Int> and InlineArray<4, Int> are different types.

When to Use InlineArray

Use InlineArrayUse Array
Size known at compile timeSize changes at runtime
Hot path needing zero heap allocationCopy-on-write sharing is beneficial
Embedded in other value typesFrequently copied between variables
Performance-critical inner loopsGeneral-purpose collection needs

Canonical Example

// Fixed-size, inline storage — no heap allocation
var matrix: InlineArray<9, Float> = [1, 0, 0, 0, 1, 0, 0, 0, 1]
matrix[4] = 2.0

// Type inference works for count, element, or both
let rgb: InlineArray = [0.2, 0.4, 0.8]  // InlineArray<3, Double>

// Eager copy on assignment (no COW)
var copy = matrix
copy[0] = 99  // matrix[0] still 1

Memory Layout

Elements are stored contiguously with no overhead:

MemoryLayout<InlineArray<3, UInt16>>.size       // 6 (2 bytes × 3)
MemoryLayout<InlineArray<3, UInt16>>.alignment  // 2 (same as UInt16)

~Copyable Integration

InlineArray supports noncopyable elements — enables fixed-size collections of unique resources:

struct Sensor: ~Copyable { var id: Int }
var sensors: InlineArray<4, Sensor> = ...  // Valid: ~Copyable elements allowed

Span — Safe Contiguous Memory Access

Span replaces unsafe pointers with compile-time-enforced safe memory views. Zero runtime overhead.

The Span Family

TypeAccessUse Case
Span<Element>Read-only elementsSafe iteration, passing to algorithms
MutableSpan<Element>Read-write elementsIn-place mutation without copies
RawSpanRead-only bytesBinary parsing, protocol decoding
MutableRawSpanRead-write bytesBinary serialization
OutputSpanWrite-onlyInitializing new collection storage
UTF8SpanRead-only UTF-8Safe Unicode processing

Accessing Spans

Containers with contiguous storage expose .span and .mutableSpan:

let array = [1, 2, 3, 4]
let span = array.span  // Span<Int>

var mutable = [10, 20, 30]
var ms = mutable.mutableSpan  // MutableSpan<Int>
ms[0] = 99

Lifetime Safety — Compile-Time Enforcement

Spans are non-escapable — the compiler guarantees they cannot outlive the container they borrow from:

// ❌ Cannot return span that depends on local variable
func getSpan() -> Span<UInt8> {
    let array: [UInt8] = Array(repeating: 0, count: 128)
    return array.span  // Compile error
}

// ❌ Cannot capture span in closure
let span = array.span
let closure = { span.count }  // Compile error

// ❌ Cannot access span after mutating original
var array = [1, 2, 3]
let span = array.span
array.append(4)
// span[0]  // Compile error: container was modified

These constraints prevent use-after-free, dangling pointers, and overlapping mutation at compile time with zero runtime cost.

Span vs Unsafe Pointers

SpanUnsafeBufferPointer
Memory safetyCompile-time enforcedManual, error-prone
Lifetime trackingAutomatic, non-escapableNone — dangling pointers possible
Runtime overheadZeroZero
Use-after-freeImpossibleCommon source of crashes

Canonical Example — Binary Parsing

func parseHeader(_ data: borrowing [UInt8]) -> Header {
    var raw = data.span.rawSpan  // RawSpan over the array's bytes
    let magic = raw.unsafeLoadUnaligned(as: UInt32.self)
    raw = raw.extracting(droppingFirst: 4)
    let version = raw.unsafeLoadUnaligned(as: UInt16.self)
    return Header(magic: magic, version: version)
}

When to Use Span

  • Replace UnsafeBufferPointer — same performance, compile-time safety
  • Performance-critical algorithms — direct memory access without copying
  • Binary parsing/serializationRawSpan for byte-level access
  • Passing data between functions — borrow the container, pass the span
  • UTF-8 processingUTF8Span for safe string byte access

Value Generics

Value generics allow integer values as generic parameters, making sizes part of the type system:

// `let count: Int` is a value generic parameter
struct InlineArray<let count: Int, Element> { ... }

// Different counts = different types
let a: InlineArray<3, Int> = [1, 2, 3]
let b: InlineArray<4, Int> = [1, 2, 3, 4]
// a = b  // Compile error: different types

Currently limited to Int parameters. Enables stack-allocated, fixed-size abstractions where the compiler verifies size compatibility at compile time.

Decision Tree

Need explicit ownership?
├─ Working with ~Copyable type?
│  └─ Yes → Required (borrowing/consuming)
├─ Fixed-size collection, no heap allocation?
│  └─ Yes → InlineArray<let count, Element>
├─ Need safe pointer-like access to contiguous memory?
│  ├─ Read-only? → Span<Element>
│  ├─ Mutable? → MutableSpan<Element>
│  └─ Raw bytes? → RawSpan / MutableRawSpan
├─ Large value type passed frequently?
│  ├─ Read-only? → borrowing
│  └─ Final use? → consuming
├─ ARC traffic visible in profiler?
│  ├─ Read-only? → borrowing
│  └─ Transferring ownership? → consuming
└─ Otherwise → Let compiler choose

Resources

Swift Evolution: SE-0377, SE-0453 (Span), SE-0451 (InlineArray), SE-0452 (value generics)

WWDC: 2024-10170, 2025-245, 2025-312

Docs: /swift/inlinearray, /swift/span

Skills: axiom-swift-performance, axiom-swift-concurrency

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

28.97%
按下载量换算357

Codex

25.67%
按下载量换算317

OpenCode

19.17%
按下载量换算237

Antigravity

12.75%
按下载量换算157

Cursor

8.85%
按下载量换算109

windsurf

3.39%
按下载量换算42

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills