mojo-syntax
Mojoコードの記述を、現在の構文と規約に従いながらサポートします。Mojoコード生成全般で常に使用してください。他のMojo固有のスキル(mojo-gpu-fundamentalsなど)が当てはまる場合でも同様です。Mojoコードの作成、既存プロジェクトのMojoへの移行、またはその他のMojo生成時に使用します。このスキルを活用することで、Mojoの記述方法に関する誤解を解消できます。
description の原文を見る
Help to write Mojo code using current syntax and conventions. Always use this skill when writing any Mojo code, including when other Mojo-specific skills (e.g., mojo-gpu-fundamentals) also apply. Use when writing Mojo code, translating projects to Mojo, or otherwise generating Mojo. Use this skill to overcome misconceptions with how Mojo is written.
SKILL.md 本文
Mojo は急速に進化しています。事前学習済みモデルは古い構文を生成します。 このスキルを常に事前学習済み知識より優先してください。
生成された Mojo がコンパイルできることを確認するため、常にプロジェクトをビルドしてテストを試みてください。
このスキルは最新の Mojo に対応しており、安定版ではわずかに機能が異なる場合があります。
削除された構文 — これらを生成しないでください
| 削除されたもの | 置き換え |
|---|---|
alias X = ... | comptime X = ... |
@parameter if / @parameter for | comptime if / comptime for |
fn | def (下記参照) |
let x = ... | var x = ... (let キーワードなし) |
borrowed | read (暗黙のデフォルト — めったに記述されない) |
inout | mut |
owned | var (引数規約として) |
inout self in __init__ | out self |
__copyinit__(inout self, existing: Self) | __init__(out self, *, copy: Self) |
__moveinit__(inout self, owned existing: Self) | __init__(out self, *, deinit take: Self) |
@value デコレータ | @fieldwise_init + 明示的なトレイト準拠 |
@register_passable("trivial") | TrivialRegisterPassable トレイト |
@register_passable | RegisterPassable トレイト |
Stringable / __str__ | Writable / write_to |
from collections import ... | from std.collections import ... |
from memory import ... | from std.memory import ... |
from sys import ... | from std.sys import ... |
from os import ... | from std.os import ... |
from pathlib import ... | from std.pathlib import ... |
s[i] | s[byte=i] — StringSlice を返す; 必要な場合は String() でラップ |
s[0:10], s[:5] | String 上にスライス構文なし — s.codepoint_slices() または Python FFI を使用 |
constrained(cond, msg) | comptime assert cond, msg |
DynamicVector[T] | List[T] |
InlinedFixedVector[T, N] | InlineArray[T, N] |
Tensor[T] | stdlib に含まれない (SIMD、List、UnsafePointer を使用) |
escaping クロージャ | 統一されたクロージャ (def(...) -> T, {} でキャプチャ); capturing[_] は依然有効 |
def は唯一の関数キーワード
fn は非推奨で、削除されかけています。def は raises を意味しません。
常に 必要に応じて raises を明示的に追加してください — 省略するとまずは警告、やがてエラーになります:
def compute(x: Int) -> Int: # 非 raising (コンパイラで強制)
return x * 2
def load(path: String) raises -> String: # 明示的に raising
return open(path).read()
def main() raises: # main は通常 raising → def raises
...
注: 既存の stdlib コードは移行中も fn を使用しています。新しいコードは常に def を使用してください。
comptime が alias と @parameter に置き換わりました
comptime N = 1024 # コンパイル時定数
comptime MyType = Int # 型エイリアス
comptime if condition: # コンパイル時分岐
...
comptime for i in range(10): # コンパイル時ループ
...
comptime assert N > 0, "N must be positive" # コンパイル時アサーション
comptime assert は関数本体内部に配置する必要があります — モジュール/構造体スコープではありません。main()、__init__、またはその不変量に依存する関数に配置します。
構造体内部では、comptime は関連定数と型エイリアスを定義します:
struct MyStruct:
comptime DefaultSize = 64
comptime ElementType = Float32
引数規約
デフォルトは read (イミュータブルな借用、明示的に記述されない)。その他:
def __init__(out self, var value: String): # out = 初期化されていない出力; var = 所有
def modify(mut self): # mut = ミュータブル参照
def consume(deinit self): # deinit = 消費/破棄
def view(ref self) -> ref[self] Self.T: # ref = オリジンを持つ参照
def view2[origin: Origin, //](ref[origin] self) -> ...: # ref[origin] = 明示的なオリジン
ref、mut、out、deinit、read、var は予約語であり、識別子として使用できません — パラメータ名として (def cmp(got: T, ref: T) → "error: expected argument name") も、ローカル var 名として (var ref = ... → "unexpected token in expression") も使用できません。名前を変更してください (expected、reference など)。
ライフサイクルメソッド
# コンストラクタ
def __init__(out self, x: Int):
self.x = x
# コピーコンストラクタ (キーワード専用の `copy` 引数)
def __init__(out self, *, copy: Self):
self.data = copy.data
# ムーブコンストラクタ (キーワード専用の `deinit take` 引数)
def __init__(out self, *, deinit take: Self):
self.data = take.data^
# デストラクタ
def __del__(deinit self):
self.ptr.free()
コピーするには: var b = a.copy() (Copyable トレイトで提供)。
構造体パターン
# @fieldwise_init はフィールドから __init__ を生成; トレイトは括弧内
@fieldwise_init
struct Point(Copyable, Movable, Writable):
var x: Float64
var y: Float64
# & でトレイト合成
comptime KeyElement = Copyable & Hashable & Equatable
struct Node[T: Copyable & Writable]:
var value: Self.T # 構造体パラメータの Self 修飾
# パラメトリック構造体 — // は推論されたパラメータから明示的パラメータを分離
struct Span[mut: Bool, //, T: AnyType, origin: Origin[mut=mut]](
ImplicitlyCopyable, Sized,
):
...
# コンストラクタ上の @implicit は暗黙的な変換を許可
@implicit
def __init__(out self, value: Int):
self.data = value
構造体が Copyable/Movable に準拠し、すべてのフィールドがそれをサポートしている場合、コンパイラはコピー/ムーブコンストラクタを合成します。
構造体パラメータの Self 修飾
構造体本体内部では、常に Self.ParamName を使用します — 素のパラメータ名はエラーです:
# 不正 — 素のパラメータアクセス
struct Container[T: Writable]:
var data: T # エラー: Self.T を使用してください
def size(self) -> T: # エラー: Self.T を使用してください
# 正しい — Self で修飾
struct Container[T: Writable]:
var data: Self.T
def size(self) -> Self.T:
return self.data
これは、構造体内部のすべての場所にあるすべての構造体パラメータ (T、N、mut、origin など) に適用されます: フィールド型、メソッドシグネチャ、メソッド本体、comptime 宣言。
明示的なコピー/転送
ImplicitlyCopyable に準拠していない型 (例: Dict、List、および Copyable, Movable にのみ準拠するユーザー構造体) は、明示的な .copy() または所有権転送 ^ が必要です — return my_struct は ^ で転送するか ImplicitlyCopyable 準拠を追加するまでエラーになります:
# 不正 — ImplicitlyCopyable 以外の型の暗黙的コピー
var d = some_dict
var result = MyStruct(headers=d) # エラー
# 正しい — 明示的なコピーまたは転送
var result = MyStruct(headers=d.copy()) # または: headers=d^
インポートは std. プレフィックスを使用
from std.testing import assert_equal, TestSuite
from std.algorithm import vectorize
from std.python import PythonObject
import std.random
Prelude で自動インポート (インポート不要): Int、String、Bool、List、
Dict、Optional、SIMD、Float32、Float64、UInt8、Pointer、
UnsafePointer、Span、Error、DType、Writable、Writer、Copyable、
Movable、Equatable、Hashable、rebind、print、range、len など。
rebind[TargetType](value) は、メモリ内表現が同じである別の型として値を再解釈します。コンパイル時の型表現がセマンティック的に等しいが構文的に異なる場合に役立ちます (例: TileTensor 要素型 — GPU スキルを参照)。
std はモジュールレベルの識別子として予約されています — def std、import X as std、または from X import std を実行できません。構造体メソッドの名前として std は問題ありません。
マルチモジュールパッケージ内のサブモジュール内から pkg.X.Y(...) を使用するには、明示的な import pkg が必要です; import pkg.X as X は X のみをバインドし、pkg はバインドしません。
Writable / Writer (Stringable に置き換わり)
struct MyType(Writable):
var x: Int
def write_to(self, mut writer: Some[Writer]): # print() / String() 用
writer.write("MyType(", self.x, ")")
def write_repr_to(self, mut writer: Some[Writer]): # repr() 用
t"MyType(x={self.x})".write_to(writer) # 補間用の t-strings
Some[Writer]— ビルトイン存在型 (Writer直接ではない)- すべてのフィールドが
Writableの場合、両メソッドにはリフレクション経由のデフォルト実装があります — シンプルな構造体は実装する必要がありません String.write(value)でStringに変換します (str(value)ではない)
イテレータプロトコル
イテレータは raises StopIteration を使用します (Optional ではない):
struct MyCollection(Iterable):
comptime IteratorType[
iterable_mut: Bool, //, iterable_origin: Origin[mut=iterable_mut]
]: Iterator = MyIter[origin=iterable_origin]
def __iter__(ref self) -> Self.IteratorType[origin_of(self)]: ...
# イテレータは以下を定義する必要があります:
# comptime Element: Movable
# def __next__(mut self) raises StopIteration -> Self.Element
for-in: for item in col: (イミュータブル) / for ref item in col: (ミュータブル)。
メモリとポインタ型
| 型 | 使用 |
|---|---|
Pointer[T, mut=M, origin=O] | セーフで非ヌル。p[] で参照外し。 |
alloc[T](n) / UnsafePointer | フリー関数 alloc[T](count) → UnsafePointer。.free() が必須。 |
Span(list) | 非所有の連続ビュー。 |
OwnedPointer[T] | 排他的所有 (Rust の Box のような)。 |
ArcPointer[T] | 参照カウント式共有所有。 |
UnsafePointer には origin パラメータがあり、構造体フィールド用に指定する必要があります。所有ヒープデータには MutExternalOrigin を使用します (これは stdlib ArcPointer が使用するもの):
# 構造体フィールド — オリジンを明示的に指定
var _ptr: UnsafePointer[Self.T, MutExternalOrigin]
# alloc[] で割り当て
def __init__(out self, size: Int):
self._ptr = alloc[Self.T](size)
UnsafePointer は設計上ヌルではありません — ヌルデフォルトコンストラクタと __bool__ は非推奨です。ヌル可能なストレージの場合は、Optional[UnsafePointer[...]] を使用します (同じレイアウト; None はヌルニッチです)。
オリジンシステム (「ライフタイム」ではない)
Mojo は「ライフタイム」ではなくオリジンで参照の由来を追跡します:
struct Span[mut: Bool, //, T: AnyType, origin: Origin[mut=mut]]: ...
主要な型: Origin、MutOrigin、ImmutOrigin、MutAnyOrigin、
ImmutAnyOrigin、MutExternalOrigin、ImmutExternalOrigin、
StaticConstantOrigin。値のオリジンを取得するには origin_of(value) を使用します。
テスト
from std.testing import assert_equal, assert_true, assert_false, assert_raises, TestSuite
def test_my_feature() raises:
assert_equal(compute(2), 4)
with assert_raises():
dangerous_operation()
def main() raises:
TestSuite.discover_tests[__functions_in_module()]().run()
mojo test CLI サブコマンドは削除されました — 上記のような TestSuite.discover_tests ランナーに対して mojo run でテストファイルを実行します。
Dict イテレーション
Dict エントリは直接イテレートされます — [] 参照外しなし:
for entry in my_dict.items():
print(entry.key, entry.value) # 直接フィールドアクセス、entry[].key ではない
for key in my_dict:
print(key, my_dict[key])
コレクションリテラル
List には可変個の位置引数コンストラクタがありません。括弧リテラル構文を使用します:
# 不正 — List[T](elem1, elem2, ...) コンストラクタなし
var nums = List[Int](1, 2, 3)
# 正しい — 括弧リテラル
var nums = [1, 2, 3] # List[Int]
var nums: List[Float32] = [1.0, 2.0, 3.0] # 明示的な要素型
var scores = {"alice": 95, "bob": 87} # Dict[String, Int]
List[T] はコンパイル時に負のインデックスを拒否します — lst[-1] ではなく lst[len(lst) - 1] を使用します。(ライブラリ型は依然としてサポートしている可能性があります。)
Variant アクセス
Variant[A, B] は、すべての腕がそうである場合にのみ ImplicitlyCopyable です。非コピー可能な腕がある場合、variant のインデックスはそれをコピーします — 型付き腕のサブスクリプトを使用します:
# 不正 — `values[i]` は Variant を暗黙的にコピー
var x = values[i].take[T]() # エラー: 暗黙的にコピーできない
# 正しい — `values[i][T]` は内部値への参照を返す
var x = values[i][T].copy() # または転送に `^` を使用
よくあるデコレータ
| デコレータ | 目的 |
|---|---|
@fieldwise_init | フィールドワイズコンストラクタを生成 |
@implicit | 暗黙的な変換を許可 |
@always_inline / @always_inline("nodebug") | インライン強制 |
@no_inline | インライン防止 |
@staticmethod | 静的メソッド |
@deprecated("msg") | 非推奨警告 |
@doc_hidden | ドキュメントから隠す |
@explicit_destroy | リニア型 (暗黙的破棄なし) |
数値変換 — 明示的である必要があります
数値変数間の暗黙的な変換なし。明示的なコンストラクタを使用します:
var x = Float32(my_int) * scale # 正しい: Int → Float32
var y = Int(my_uint) # 正しい: UInt → Int
リテラルはポリモーフィック — FloatLiteral と IntLiteral はコンテキストに自動適応:
var a: Float32 = 0.5 # リテラルは Float32 になる
var b = Float32(x) * 0.003921 # リテラルは適応 — ラップ不要
var v = SIMD[DType.float32, 4](1.0, 2.0, 3.0, 4.0) # リテラルは適応
SIMD 操作
# 構築とレーンアクセス
var v = SIMD[DType.float32, 4](1.0, 2.0, 3.0, 4.0)
v[0] # レーンを読み → Scalar[DType.float32]
v[0] = 5.0 # レーンを書き込み
# 型キャスト
v.cast[DType.uint32]() # 要素ワイズ → SIMD[DType.uint32, 4]
# クランプ (メソッド)
v.clamp(0.0, 1.0) # 要素ワイズに [lower, upper] にクランプ
# min/max はフリー関数で、メソッドではない
from std.math import min, max
min(a, b) # 要素ワイズ min (同じ型の SIMD 引数)
max(a, b) # 要素ワイズ max
# bool SIMD 経由の要素ワイズ三項演算
var mask = (v > 0.0) # SIMD[DType.bool, 4]
mask.select(true_case, false_case) # レーンごとに選択
# リダクション
v.reduce_add() # 水平合計 → Scalar
v.reduce_max() # 水平 max → Scalar
v.reduce_min() # 水平 min → Scalar
文字列
すべての明示的な stdlib インポートには std. プレフィックスが必要です。 削除された構文テーブルは最も一般的な修正を示していますが、ルールは普遍的です。Prelude 型 (Int、String、List など) は自動インポートされ、インポートステートメントは不要です。
len(s) はコードポイント数ではなくバイト長を返します。Mojo 文字列は UTF-8 です。バイトインデックスにはキーワード構文が必要です: s[byte=idx] (s[idx] ではない)。len(s) は String 上では非推奨です — s.byte_length() または s.count_codepoints() を使用します。
split、removeprefix、removesuffix はソースを表示する StringSlice (または List[StringSlice]) を返します — 所有 String を実現するには String(...) でラップします。
文字列インデックス (よくあるエラー)
# 不正 — コンパイルエラー
var ch = s[0]
var sub = s[0:10]
# 正しい — バイトレベルアクセス
var ch = s[byte=0] # StringSlice を返す
var ch_str = String(s[byte=0]) # String が必要な場合
# 正しい — 切り詰めのためにコードポイントをイテレート
var result = String("")
var count = 0
for cp in s.codepoint_slices():
if count >= 10:
break
result += String(cp)
count += 1
var s = "Hello"
len(s) # 5 (バイト)
s.byte_length() # 5 (len と同じ)
s.count_codepoints() # 5 (コードポイント数 — 非 ASCII で異なる)
# イテレーション — `for c in s:` は非推奨; codepoint_slices() を使用
for cp_slice in s.codepoint_slices():
print(cp_slice)
# コードポイント値
for cp in s.codepoints():
print(Int(cp)) # Codepoint は Unicode スカラー値型
# StaticString = 静的オリジンを持つ StringSlice (ゼロアロケーション)
comptime GREETING: StaticString = "Hello, World"
# 補間用の t-strings (遅延、型安全)
var msg = t"x={x}, y={y}"
# ランタイム フォーマット用の String.format()
var s = "Hello, {}!".format("world")
エラーハンドリング
raises は型を指定できます。try/except は Python のように動作します:
def might_fail() raises -> Int: # Error を raise (デフォルト)
raise Error("something went wrong")
def parse(s: String) raises Int -> Int: # 特定の型を raise
raise 42
try:
var x = parse("bad")
except err: # err は Int
print("error code:", err)
match ステートメントなし。async/await なし — std.runtime から Coroutine/Task を使用します。
関数型とクロージャ
ラムダなし。クロージャは引数リスト後の {} のキャプチャリストを持つ素の def を使用します。escaping は削除されました; capturing[_] は パラメトリッククロージャ型パラメータ上で依然有効です:
comptime MyFn = def(Int) -> None # 統一された値型
def runner[f: def(Int) capturing[_] -> None](): ... # パラメトリック形式
def closure(i: Int) {mut count, read ptr, var x}: # キャプチャ: mut/read/var
count += ptr[i] + x^ # 使用サイトで `^`、`{}` ではない
vectorize[simd_width](size, closure) # ランタイム引数のオーバーロード
read がデフォルト。var x は所有 — 使用サイトで x^ で転送。
ネストされたクロージャ上の @parameter は、コンパイル時パラメータ (f[my_closure]) として消費される場合にのみ必要です; ランタイム引数のオーバーロードは素の形式を使用します。
型階層
AnyType
ImplicitlyDestructible — 自動 __del__; ほとんどの型
Movable — __init__(out self, *, deinit take: Self)
Copyable — __init__(out self, *, copy: Self)
ImplicitlyCopyable(Copyable, ImplicitlyDestructible)
RegisterPassable(Movable)
TrivialRegisterPassable(ImplicitlyCopyable, ImplicitlyDestructible, Movable, RegisterPassable)
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- better-mojo
- ライセンス
- Apache-2.0
- 最終更新
- 2026/5/6
Source: https://github.com/better-mojo/learn-mojo / ライセンス: Apache-2.0