世界を動かす技術を、日本語で。

Swiftはより便利なRustです

概要

  • RustSwift の類似点と相違点の解説
  • メモリ管理や型システムなど 設計思想の違い に注目
  • Swiftの利便性Rustのパフォーマンス のトレードオフ
  • Swiftの クロスプラットフォーム対応 の現状
  • 両言語の 活用分野 と今後の展望

RustとSwiftの特徴比較

  • Rust は「所有権」概念を導入し、 ガーベジコレクションや参照カウント なしでメモリ管理を実現

  • 低レベル操作 が必要な場合はunsafeシステムや生Cポインタの利用が可能

  • Rc、Arc、Cow などのユーティリティで参照カウントや「clone-on-write」もサポート

  • 関数型言語の機能 (タグ付きenum、match式、第一級関数、強力なジェネリクス型システム)を搭載

  • LLVMベースのコンパイラ でネイティブコードやWASMへのコンパイルに対応

  • Swift も関数型言語の特徴(タグ付きenum、switch式、第一級関数)を持つ

  • 強力な型システム とジェネリクスを搭載

  • 値型 がデフォルトで「コピーオンライト」セマンティクス

  • パフォーマンス重視時は 所有権システム や「move」による値の転送も可能

  • 低レベル操作時はunsafeシステムや生Cポインタにアクセス可能

  • LLVMベースのコンパイラ でネイティブコードやWASMにも対応

メモリ管理モデルの違い

  • Rust はシステムプログラミング言語として「ボトムアップ」設計
    • 低レベルが基本、必要に応じて高レベル機能を追加
  • Swift は「トップダウン」設計
    • 高レベルが基本、必要に応じて低レベル操作が可能
  • Swift のデフォルトは「コピーオンライト」値型
    • RustでいうCow<>が全値に適用されているイメージ
  • Rust は「move」や「borrow」が簡単、Cow<>には追加の手続きが必要
  • Swift は「コピーオンライト」が簡単、moveやborrowには追加の手続きが必要

構文と機能の違い

  • Swift はC言語風の構文で機能を隠蔽
    • 例:match式ではなくswitch文を使うが、実態はパターンマッチング式
    • enumに直接メソッドを定義可能
  • Rust のmatchとSwiftのswitchの比較コード例
    • Rust: match coin { ... }
    • Swift: switch coin { ... }

オプショナル型とエラー処理

  • Rust はnullを持たず、Noneを利用

  • Swift はnilだが、実態はNoneのラッパー

    • Option<T>に相当するT?型
    • if let構文で安全にアンラップ可能
    • Some(val)のラッピング不要、Swiftコンパイラが自動変換
  • Rust はResult型によるエラー処理

  • Swift はdo-catchブロックとtryキーワードを使用

    • 実装はRustのResult型と同様、構文を親しみやすく偽装

再帰型とコンパイラのアプローチ

  • Rust の自己参照enumはBox<>などの明示的なラッピングが必要
  • Swift はindirectキーワードで再帰型を指定
    • 以降はコンパイラが自動でメモリ管理を実施

Swiftの実用性と進化

  • Swift はObjective-C互換性や実用性を重視した設計
  • 多機能で大規模な言語、 段階的な学習 を促進する設計
  • 主要な言語機能
    • クラス/継承
    • async-await、async-sequences、アクター
    • プロパティラッパー、lazyプロパティ、getter/setter
    • Result Builder(SwiftUIやHTML生成など)

利便性とパフォーマンスのトレードオフ

  • Swift は習得が容易で生産性が高い
  • Rust はデフォルトで高速、Swiftはデフォルトで簡単
  • Rustはシステム・組み込み・コンパイラ・OS開発に最適
  • SwiftはUI・サーバー・一部のシステム開発に最適
  • 今後は両者の適用範囲の重複が拡大する見込み

Swiftのクロスプラットフォーム展開

  • Swift はApple専用言語とのイメージが強かったが、現状は異なる
  • WASM対応swift-wasm の本体統合
  • Windows版Swift はArcブラウザの移植等で利用
  • Linux版Swift はApple公式サポート、Swift on Serverも推進
  • Embedded Swift はPanic Playdate等の小型デバイスで採用
  • 公式サイトで多様なプロジェクトを紹介
    • Windows、Linux、Playdate、Gnomeアプリなど
  • Swiftの相互運用性 が強み
  • XCode以外の開発環境整備も進行中(LSPやVSCode拡張など)

Swiftの課題と今後

  • コンパイル時間 はRust同様に長い
  • 機能過多や言語仕様の肥大化
  • 一部構文が直感的でない
  • パッケージエコシステム はRustに劣る
  • しかし「Apple専用」という認識は既に過去のもの
  • クロスプラットフォーム、ABI安定、GCなし、ARC、自動所有権管理 を実現
  • Linux対応パッケージの増加、FoundationのOSS化
  • クロスプラットフォーム開発向けのRust代替言語としてSwiftが現実的な選択肢に進化

まとめ

  • RustSwift は多くの機能や思想を共有しつつ、設計の出発点やデフォルトの選択肢が異なる
  • Swift は利便性・親しみやすさを重視しつつ、クロスプラットフォーム言語として進化中
  • 両者の強みを理解し、 用途に応じた最適な選択 が重要

Hackerたちの意見

同じ(速い馬?)でも、Rustを使いたいな。大手テック企業に依存してないから、もし彼らが見捨てたとしても大丈夫だし。フォークとして続く可能性はあるけど、開発のスピードは落ちちゃうだろうね。

もしどの言語がサポート不足で衰退するか心配するなら…「Appleがサポートをやめる」なんて、誰もそのリストに入れないと思うよ。Rustはサポートを失うリスクが高いね。

ウィキペディアのページの最初の文 [1]: > Swiftは、2010年にApple Inc.のためにChris Lattnerによって作られ、オープンソースコミュニティによって維持されている高水準の汎用、マルチパラダイム、コンパイル型プログラミング言語です。記事が繰り返しているように、Apple特有のものではないよ。 [1] https://en.wikipedia.org/wiki/Swift_(programming_language)

今やAppleのソフトウェアの多くはSwiftで書かれてるよ。彼らがその言語を捨てるのは多分利益にならないだろうね。

Rustを使いたいのは、大手テック企業に依存してないからだよね。もし彼らが気に入らなければ、簡単に捨てられちゃうから。Goの開発はGoogleに依存してて、Google内で広く使われてるし。C#もMicrosoftの.NETに依存してるし、Swiftもオープンソースでない限り、あんまり変わらないよね。だから、これはあまり意味のない議論だと思う。

木を表すenumを考えてみて。再帰的な型だから、Rustでは自分自身の中で型を参照するためにBoxみたいなものを使わなきゃいけないんだ。 > > enum TreeNode { > Leaf(T), > Branch(Vec>>), > } > > (Box>>を使ってもいいけど)これは間違いだよ。ここでBoxは必要ない。Rustのコンパイラは間接参照の層を求めるけど、Vecがそれを既にやってるから。

さらに言うと、Swiftが良いレベルの糖衣を持っていると言って、enumを例に挙げるのはちょっと無理があるよ。Swiftのユニオン型の話は本当に貧弱で、状態を適切にモデル化する代わりに、今でも多くの人がビューでオプショナル型を大量に使ってる。実際にSwiftのenumやプロトコルを使うのが痛いからね。

それは違うと思う。Rust 1.92でのテスト、enum Tree { Lead(T), Branch(Vec>), } は全然問題なく動くし、余計なBoxも必要ないよ。

ここではBoxは必要ないよ。Vecはすでにヒープデータへの固定サイズのハンドルだから。

一つの意味では、Rustの間違っているところは気にならないんだ。もうRustをよく知ってるから。でも結局は気になる。Swiftも同じように間違っているだろうけど、どこがどう間違っているのかがわからないから。例えば、「実際、Swiftはenumを単なる型以上のものとして扱い、メソッドを直接載せることができる」というのは、「単なる型」にはメソッドがないと仮定しているように思える。これはC++から来たらそう思うかもしれないけど、RustはC++じゃないから、もちろんすべての型、ユーザー定義のenumや構造体、さらには共用体もメソッドを持てるし、組み込みのプリミティブ型もすべてメソッドを持ってる。'F'.to_digit(16).unwrap() // は32ビットの符号なし整数定数15だよ。もっと具体的な例を挙げると、Rustのポインタの出所APIは、生のポインタにメソッドを提供して、整列されたポインタの下にあるブールフラグビットを隠すようなクロージャを受け取ることができる。最終的にCPUアドレスレジスタでXORに落ちるからといって、メソッド構文を使えないわけじゃない。21世紀なんだから。

君の言ってることは間違ってないけど、VecBoxの違いについて、君の言い方だと微妙に混乱する人がいるかもしれないと思う。ここでのVecの重要な特徴は、間接参照じゃなくて、コンパイル時にサイズが決まることだと思う。Boxと比べると、コンパイル時にサイズが決まっていない型(例えば、dynトレイトオブジェクト)に対して意味のある間接参照を提供しないし、それらをVecの中に格納するにはBoxかそれに類似したものが必要になるよ。

大体同意だけど、ほとんどのことに言えるように、細かいところが問題なんだよね! - Xcode。スケールで苦労する本当に粗いIDEで、パッケージのリフレッシュや多くのターゲットで詰まっちゃう。修正したいときにバイナリパッチすらできない特別な権限があるし! - ビルドシステム。CargoはSPMよりずっと扱いやすいよ。 - マクロのサポート、コード生成はまだマクロシステムの外で行われてることが多いから、使われ方が示されてる。 - リンター/フォーマットのサポート。うん、あるにはあるけど、最後にチェックしたときはちょっと悪化してた。 - パフォーマンス。Swiftには多くのパフォーマンスの崖があって、ほとんどは十分にやる気のあるコンパイラ開発者が修正できるけど、今のところは言語についてそのまま話してるわけじゃないね。 - 型推論の時間。Swiftの双方向型推論は複雑な式で詰まることが多くて、SwiftUIの一番の使い道にとっては本当に問題だよ。 - 上記の悪化要因として、インポートはすべて暗黙的にモジュールスコープになってるから、1つのファイルを変更するとモジュール内のすべてのファイルの型を再計算しなきゃいけない。SPMとXcodeが複数のターゲットで苦労するから、通常は1つの変更で全てのSwiftファイルを再コンパイルすることになる。 - クラスと構造体の奇妙さ?objcとの互換性のためにそうせざるを得なかったのはわかるけど、最初からクラスを置き換える何か、例えば完全に糖衣されたfinal class Boxみたいなのがあれば、もっとクリーンだったと思う。ほとんどの場合、Rustの方が簡単であるべきだとは思うけど、双方向型推論をカット演算子なしで含めたり、ツールが貧弱だったりすると、TypeScriptを使って型チェックのコンパイルの頭痛を完全に回避できるケース以外では、実際にどこが簡単なのか見つけるのが難しいよ。

iOS/macOSアプリを開発していないなら、Xcodeは完全にスキップして、swift CLIを使えばいいよ。これでも全然問題ないからね。(LinuxやWindowsでもちゃんと動くし。)

ちなみに、XcodeなしでEmacsだけでmacOSのCocoa+Swiftアプリを作ったことあるよ。Makefileだけでね。必ずしも必要ってわけじゃないよ。

完全に同意。Xcodeは最悪だよ。あのチームは色々大変だと思うけど、ほんとにゴミみたいなソフトウェアを作ってるよね。

そうだね!どちらかを主張している人たちが両方試したかどうかは分からないけど、あなたがその痛みを知っているのは明らかだよ。

小さなSwiftUIアプリを作ったんだけど、メモリリークの特定が本当に難しかった。実際、まだ見つけられてないリークがあるんだ。なぜかヒープは大丈夫なのに、アプリは仮想メモリをどんどん割り当て続ける。コードを分析するためにClaudeやGeminiを使って、vmmapやInstrumentsも使わせて、リークを再現するためにコードをループさせても、結局リークが続いて、毎日数十メガバイトずつ増えていく。きっと目の前にあるシンプルな問題なんだろうけど、Swiftのちょっと自動だけど完全には自動じゃないメモリモデルのせいで、RustやGoよりもメモリについて考えるのがずっと難しいのは確かだね。

Swiftのコンパイル遅延のほとんどは、パッケージを使ってコンポーネント化することで避けられるし、型推論に頼らずに型を明示的にするようなちょっとしたコツもあるよ。でも、SPMでそんなに苦労してる理由は分からないな。ほとんどの人はうまく使ってるみたいだし。

Xcodeの愚痴がまだ理解できない。SwiftはLSP対応のテキストエディタ(VSCodeにはSwift用の公式拡張もあるし、zedやSublime Textなどでも使える)で使えるよ。Apple特有の開発をしてない限り、Xcodeは必要ないよ。

Xcodeは、今まで使った中で最悪のIDEだと思う。2010年のEclipseの方が2025年のXcodeよりマシだったよ。

XcodeはSwiftでプログラムするのに必要ないよ。私はたくさん書いてるけど、Xcodeは一度も開いたことがない。LSPサポートのあるターミナルエディタが素晴らしいんだ。

SPMとCargoについて気になるんだけど、Cargoが優れている基本的なデザインの決定があるの?それとも今の状態の特異性なのかな?

Rustの便利さをもっと求めて、Rustの借用チェッカーに悩みたくないなら、Swiftに切り替える必要はないよ:Rustの参照カウントに頼れるから。1.) Rustの参照カウントスマートポインタ[1]を使って共有可能な不変参照を、2.) Rustの内部可変性[2]を使ってランタイムでチェックされる非共有の可変参照を使えばいい。実質的には、少し冗長なGolangを書くことになるけど、Rustの表現力は保てるよ。 [1] https://doc.rust-lang.org/book/ch15-04-rc.html [2] https://doc.rust-lang.org/book/ch15-05-interior-mutability.h...

でも、すごく冗長になっちゃうよね!

それに、マルチスレッド環境じゃなければ、Rc(非アトミック参照カウント)を使えるよ。アトミック版はArcで、C++のshared_ptrに似てる。Rcを使うのに特に難しいことはないよ。具体的には、Rcをスレッド間で誤って使うことはできないから、コンパイラがSendマーカートレイトのおかげでそれを防いでくれるんだ。

SwiftはAppleプラットフォーム専用の良い言語だという印象がある。昔はそうだったけど、今はもう違うし、Swiftはどんどんクロスプラットフォームの良い言語になってきてる。非Appleプラットフォームでの開発者体験って実際どうなの?Linuxがメインプラットフォームだけど、ほとんどのSwiftエコシステムはApple向けだと思う。ライブラリ、ツール、ドキュメント、IDE、チュートリアルとか、全部Appleを使う前提になってる。Appleデバイスを使わずにSwiftを使ってる人、誰か教えてくれない?

自分のMacのCLIツールをLinuxにコンパイルしようとしたことがあるんだけど、最近はLLMを使って実行する方が速くて、向こうでかなり良いGoが得られるし、そっちの方がクロスコンパイルもずっと簡単なんだよね。新しいAndroidサポートも見てるけど(リンクは手元にないけど)、魅力的だなと思う。でもKotlinを知ってるし、Android用にはシンプルなMakefileとJDKだけで開発してきたから、特別なツールは必要ないんだよね…。

いや、そうじゃないよ。Appleの開発者たちは、Linuxでの開発が素晴らしいって言うし、MSの人たちもC#について同じことを言うよ。Rustは特定のプラットフォームのために設計されてないから、その点は明らかだね。特にLinuxのエコシステムは素晴らしいよ。

Swiftは、Swiftコンパイラを管理するのが大変だよね(rustupに相当するもの)。LSPは結構うまく動いてる。Appleが作る(オープンソースの)ライブラリのほとんどはクロスプラットフォーム対応だし。個人的には、自分のライブラリも全プラットフォームで動くように気を使ってるよ、Windowsでもね!(ちょっとしたエピソードだけど…)。全体的にはまだ完璧じゃないけど、少しずつ良くなってきてるし、その方向で進んでいくつもり。

私の経験では、すごくイライラする。AppleのドキュメントにはLinuxで動くものやその制限について全く触れられてないから、結局は推測したり試行錯誤で解決するしかないんだ。ウェブソケットクライアントを書こうとしたんだけど、https://willhbr.net/2023/08/23/the-five-stages-of-swift-on-l... それから2年後に再挑戦したら、https://willhbr.net/2025/10/13/the-6-2nd-stage-of-swift-on-l...

そうだね、私の経験ではAppleのバイアスが、読んでいる記事やハウツーにあって、つまずくことがあるんだ。もう何年も前の話だけど、キーに弱いメモリを持つSetを作りたかったんだ。読んだものは「NSHashTableを使えばいいよ」って言ってて、素直に従ったんだけど(Foundationにあるからね)、クロスコンパイルしようとしたらAppleプラットフォーム以外では存在しなかったんだ。インポートしたからって使えないってことが明確にわかるわけじゃなかったけど、結局使えなかった。

ちょっと違うと思うな。Rustの基本にはゼロコスト抽象の概念があるけど、Swiftはそれをやってない。私の見解では、Rustの多くの機能はゼロコストルールに従うために特別に選ばれてると思う。所有権モデルとかね。

Rustの明示的な所有権モデルは、Swiftのアクターやタスクの足元をすくわれるリスクから守ってくれるんだよね。Rustでは、その分野でのほとんどのミスがビルド時エラーになるから、時間の節約になるし、学びながら改善するのにも役立つんだ。

Swiftも所有権モデルをサポートしてるよ。

Swiftは素晴らしい言語だけど、サーバーサイドのソフトウェアには向いてないね。エコシステムが小さすぎて、GoやRustの代わりに使うメリットがない。VS Codeでもまあまあ動くけど、Xcodeは絶対に使いたくない。Kotlinもサーバーサイドでの採用を狙って似たようなことを試みたけど、サーバーサイドプログラミングは競争が激しいから、他のJVM言語でdistsysコードを書くのはあまり好まれない。Swiftはその点で少しマシかな。手軽に使える言語が欲しいなら、PythonやTypeScriptで十分だし、パフォーマンスが重要で高い同時実行性が求められる環境ではGoが強いよ。多くの運用ツールやインフラコードはGoで書かれてるし、システムプログラミングや組み込みコードにはRustがいい選択だね。だから、X言語の構文について考えるのは楽しいけど、実際には次の非おもちゃのバックエンドdistsysの仕事にSwiftを選ぶのはあまり現実的じゃないよ。それに、Appleの立場を考えると、彼らの囲いの中でうまく動く言語を選ぶのはあまり嬉しくないな。

個人的なプロジェクトでSwift Vaporを使ってるけど、すごくいいよ。今はGoもたくさん使ってるから、いくつかのプロジェクトではちょっと後悔してる。エージェントコーディング(成功状態に導くための善循環にエージェントを入れることが目標)をしてるとき、Swiftだとコンパイルやテストの速度が遅く感じるんだよね。

Windows上のSwiftはThe Browser Companyによってコードを共有し、ArcブラウザをWindowsに持ってくるために使われている。Arcはもはや開発されていない(http://www.newswarner.com/2025/05/27/the-browser-company-exp...)し、私の知る限り、彼らのSwiftをWindowsに移植する努力はキャンセルされたみたい。

ちなみに、Swift for Windowsってのがあるよ(https://www.swift.org/install/windows/)。新しいWindows専用の作業グループもできたみたいだね: https://www.swift.org/blog/announcing-windows-workgroup/

Swiftにはマッチステートメントや式がない。開発者がすでに慣れているswitchステートメントがある。ただ、このswitchステートメントは実際にはswitchステートメントじゃない。式なんだ。「フォールスルー」しないし、パターンマッチングをする。名前と構文が違うだけのマッチ式なんだ。誰かが「マッチ」ステートメントを見て、両手をテーブルに叩きつけて、「WHAT THE ___ って-------マッチステートメント?!!!これ、めっちゃ$%^&@*#%&混乱する!!その言葉知らない!!スイッチしか知らない!!」って叫ぶ人いる?

コード内で参照カウントと「右側でのクローン」を行う この記事の雰囲気はそういう感じだったの?