﻿<?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Xheldon Blog</title>
        <description>The Answer to Life, the Universe and Everything is...</description>
        <link>https://www.xheldon.com/ja/</link>
        <atom:link href="https://www.xheldon.com/ja/feed.xml" rel="self" type="application/rss+xml" />
        <pubDate>Wed, 03 Jun 2026 01:26:21 +0000</pubDate>
        <lastBuildDate>Wed, 03 Jun 2026 01:26:21 +0000</lastBuildDate>
        <generator>Hexo v7.3.0</generator>
        
        <item>
            <title>デュアルブートシステム間で同じショートカットキーを使う方法</title>
            <description>&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;私が最後にWindowsを使ったのは10年前の学生時代で、使っていたのはLenovo Y470-Pでした。このノートパソコンには設計上の欠陥があり、一度ディスプレイを閉じた際に部品が焼損してしまい、最終的にはマザーボードを交換する羽目になりました。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-809c-9b03-ca17b71cfe98.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;卒業後すぐに2015年製の15インチMacbook Proを購入し、その後数年でマシンは変わりましたが、ずっとAppleのエコシステムにいたため、Windowsの使用体験は10年前のまま止まっていました：エコシステムの分断、ソフトウェアの使いにくさ、デザインの醜さ（これは今も変わらない）、そして不合理なインタラクションデザイン。&lt;/p&gt;
&lt;p&gt;618セールで中高スペックのPCを組み立てました。14700KF、5070Ti、Crucialの64GB 6400MHzメモリと2TB SSDを搭載し、今では手放せません：高性能なWindowsマシンはこんなに滑らかだったのかと。システムデザイン言語は相変わらず不合理ですが、ソフトウェアの起動速度や優れたアプリのデザイン言語（例えばWindows版Apple Musicなど）はとても良いです。もちろん最も重要なのは、Windowsを購入した理由がゲーム（80%）とプラットフォーム固有のコードであるC#を書くため（20%）だということです。&lt;/p&gt;
&lt;h2 id=&#34;効率的な入力の本質&#34;&gt;効率的な入力の本質&lt;/h2&gt;
&lt;p&gt;長期間（9年間）MacでHHKBを使用してきたため、MacのHHKBキーマッピングをWindowsにも適用したいと考えています。これは習慣的な理由だけでなく、以下の考慮事項によるものです：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;行頭移動、行末移動、右削除などのテキスト編集で頻繁に使う機能は、Windowsでは専用キー（Home、End、Delなど）を押す必要があり、修飾キー＋キーの組み合わせでは実現できません。しかしMacではシステムレベルでEmacsキーバインドがサポートされており、Control+Aで行頭、Control+Eで行末、Control+Dで右削除が簡単に実現できます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上下左右のカーソル移動も同様で、Windowsでは専用の方向キーを使いますが、MacではControl+B/F/N/Pで実現できます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;なぜWindowsの単独キーではなく、Macの修飾キー＋ショートカットの組み合わせを好むのか疑問に思うかもしれません。&lt;/p&gt;
&lt;p&gt;この疑問の答えこそが、私がHHKBの60%配列を特に気に入っている理由です：&lt;strong&gt;手のひらを大きく動かさずにすべての操作が完了でき、入力効率を保証できる&lt;/strong&gt;からです。&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; プログラマーの世界では、マウスを使える場面でキーボードを使わないと刑に処されます！&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;例えば、Windowsで高速に入力中に、前に書いた部分に誤字があることに気づき、数文字削除する必要がある場合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;右手をアルファベット領域から離し、人差し指で右下の方向キーを探す（87キー以上のキーボードなら探す必要はないが）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;方向キーを押してカーソルを移動&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;右手を方向キーから離し、Backspace位置に移動&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;削除キー（Backspace）を押す&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;MacのHHKB配列なら、左手だけで同じ操作が可能です：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;左手小指でControl+Bを押してカーソル移動&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;右手小指でBackspaceを押すか、左手小指でControl+H/D（左/右削除）を押す&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これだけです。&lt;strong&gt;手をホームポジションから離す必要がありません&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;修正後も、Windowsでは右手を再び動かしてEndキーを押す必要がありますが、Macでは左手でControl+Eを押すだけで済みます。&lt;/p&gt;
&lt;h2 id=&#34;苦労するバッククォート-の入力&#34;&gt;苦労するバッククォート ` の入力&lt;/h2&gt;
&lt;p&gt;HHKBを気に入っているもう一つの理由は、フロントエンド開発者としてバッククォート（チルダのキー）を頻繁に使うからです。一般的な60%キーボードではこのキーはESCに配置され、修飾キー組み合わせで入力します。しかしHHKBではこのキーを独立させて右上に配置し、Deleteキーを下に、&lt;code&gt;｜&lt;/code&gt;キーを上に移動することで実現しています（通常のBackspaceが2つの1uキーに分割された形です）。&lt;/p&gt;
&lt;p caption=&#39;普通60配列&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/248800e8-7a61-8098-b185-c92a8eaf2c94.webp&#39; alt=&#39;普通60配列&#39; title=&#39;普通60配列&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;HHKB 配列&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/248800e8-7a61-804c-bc1a-e7a740ecc5e9.webp&#39; alt=&#39;HHKB 配列&#39; title=&#39;HHKB 配列&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;苦労するcontrolキーの入力&#34;&gt;苦労するControlキーの入力&lt;/h2&gt;
&lt;p&gt;一般的なキーボード配列で入力効率に影響するもう一つの設計は、Controlキーが左下にあることです。Control＋キーを押すとき、手首は必ず左に曲がり、手のひらは右に移動します。手のひらを動かす必要のある入力方法はエレガントではなく、効率に影響します。&lt;/p&gt;
&lt;p caption=&#39;普通键盘位置尴尬的 Ctrl&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/248800e8-7a61-809a-af2b-fab48765e5cb.webp&#39; alt=&#39;普通键盘位置尴尬的 Ctrl&#39; title=&#39;普通键盘位置尴尬的 Ctrl&#39;&gt;&lt;/p&gt;
&lt;p&gt;ただし、ネット上には小指の下の手のひら部分で左下のCtrlを押そうとする試みもありますが、これは不合理です：&lt;/p&gt;
&lt;p caption=&#39;左侧手掌按 Ctrl 法&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/248800e8-7a61-80c4-8ba9-ffdccbbec543.webp&#39; alt=&#39;左侧手掌按 Ctrl 法&#39; title=&#39;左侧手掌按 Ctrl 法&#39;&gt;&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 私は極端に、口を開閉して発音する言語はエレガントではないと考えています。エレガントな言語の発音は口を大きく開閉する必要がなく、舌と喉の協調だけで明確に発音できるべきです。そのため日本語が最もエレガントな言語だと考えています——これは同時に日本語の表現力、特に強い感情を表す罵倒語の面で弱いことにもつながっています。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;余計なcapslockキー&#34;&gt;余計なCapsLockキー&lt;/h2&gt;
&lt;p&gt;長時間にわたって頻繁に大文字を入力する人はほとんどいないと思うので、一般的なキーボード配列でCapsLockキーを左手小指という重要な位置に配置するのは全く理にかなっていない。&lt;/p&gt;
&lt;p caption=&#39;用处不多的 CapLock 占据了一个黄金位置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/248800e8-7a61-8088-9b22-efdde222997e.webp&#39; alt=&#39;用处不多的 CapLock 占据了一个黄金位置&#39; title=&#39;用处不多的 CapLock 占据了一个黄金位置&#39;&gt;&lt;/p&gt;
&lt;p&gt;以上のことから、HHKBの配列が最も完璧だと考えています。その対称美だけでなく、入力効率の高さも理由です。また、Macのショートカットキー、少なくともテキスト操作の効率性においてはWindowsを上回っています。&lt;/p&gt;
&lt;p&gt;そこで、次に&lt;strong&gt;Macのキー配置をWindowsに再現する方法&lt;/strong&gt;を共有します。これにより、両OSで同じ手の筋肉記憶を使って効率的に編集できるようになります。&lt;/p&gt;
&lt;p caption=&#39;HHKB 配列 Control 在 CapLock 位置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-80e6-8b9e-cda2586acf71.webp&#39; alt=&#39;HHKB 配列 Control 在 CapLock 位置&#39; title=&#39;HHKB 配列 Control 在 CapLock 位置&#39;&gt;&lt;/p&gt;
&lt;p&gt;HHKBで最も批判されがちな方向キーについてですが、基本的に方向キーでカーソルを移動できる場所ではEmacsのショートカットが使えます。ただし……Pythonなどの一部のターミナルではControl-DがCLI終了になってしまったり、Remote SSH接続時のLinuxホストでは問題が発生します。これは確かに厄介ですが、良いターミナルを使うことで多少回避可能です。Warpを検討してみてください。このターミナルはテキストエディタのようにコマンドを入力できるため、Emacsショートカットでコマンド入力が可能です。言葉ではわかりにくいかもしれませんが、試せば通常のターミナルとの違いがわかるでしょう。&lt;/p&gt;
&lt;h2 id=&#34;キーボード要件&#34;&gt;キーボード要件&lt;/h2&gt;
&lt;p&gt;マルチレイヤーキーマッピングをサポートしたキーボードが必要です。つまりFNキー＋他のキーの組み合わせが可能なものです。マクロ機能はあってもなくても構いません。6層までのマッピングをサポートするキーボードもあります（デュアルシステム切り替えで各システム3層）。私は新しく購入した&lt;strong&gt;Nuphy Air75 V3&lt;/strong&gt;を使用しています。HHKBではなくこれを選んだ理由は、WindowsでゲームをするためFキー（F1～F12）が必須で、75キーが私の許容できる最小サイズだからです。&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 砲車をミスったら即座に？マークを送信する —— Faker&lt;/p&gt;&lt;/blockquote&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-8072-a06b-f6c9ead05059.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;fnキーマッピングでecmacsテキスト編集を実現&#34;&gt;FNキーマッピングでEcmacsテキスト編集を実現&lt;/h2&gt;
&lt;p&gt;以下のテキスト編集機能を実装します（記載形式はWindowsキー → Macショートカット）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;行頭に移動：Home → Control + A&lt;/li&gt;
&lt;li&gt;行末に移動：End → Control + E&lt;/li&gt;
&lt;li&gt;下に移動：↓ → Control + N(Next)&lt;/li&gt;
&lt;li&gt;上に移動：↑ → Control + P(Previous)&lt;/li&gt;
&lt;li&gt;左に移動：← → Control + B(Back)&lt;/li&gt;
&lt;li&gt;右に移動：→ → Control + F(Front)&lt;/li&gt;
&lt;li&gt;右削除：Del → Control + D(Delete)&lt;/li&gt;
&lt;li&gt;左削除：Backspace → Control + H(Hが削除を表すのは歴史的経緯によるものです。興味があれば調べてみてください)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 個人的にはMacでのコピー＆ペーストにControl+C/VではなくCmd+C/Vを使う設計が好みです（ただしマッピングはしていません）。おそらくEcmacsが歴史的にコピー＆ペーストをサポートしておらず、テキスト編集特有のショートカットでもないため、Macではコピー＆ペーストの修飾キーをCMDに設定したのでしょう。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;したがって、WindowsでMacのHHKBと同じキー配置を実現するには&lt;strong&gt;CapsLockをFNレイヤーに変更する&lt;/strong&gt;必要があります（私はFN6に設定しました）。その後、各キーを個別にマッピングします：&lt;/p&gt;
&lt;p caption=&#39;修改 CapLock 为 FN6 层&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-80d2-bbf1-e143863958db.webp&#39; alt=&#39;修改 CapLock 为 FN6 层&#39; title=&#39;修改 CapLock 为 FN6 层&#39;&gt;&lt;/p&gt;
&lt;p&gt;FN6レイヤーで各キーをWindowsの対応機能にマッピングします：&lt;/p&gt;
&lt;p caption=&#39;FN6 层映射&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-809e-897f-e5af7ec726c4.webp&#39; alt=&#39;FN6 层映射&#39; title=&#39;FN6 层映射&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;アルファベット領域のキー変更&#34;&gt;アルファベット領域のキー変更&lt;/h2&gt;
&lt;p&gt;HHKBではEnterキーの上にDeleteキー&lt;code&gt;Backspace&lt;/code&gt;があり、&lt;code&gt;｜&lt;/code&gt;キーではありません。当初はBackspaceと｜キーを入れ替えていましたが、不思議なことに手が75キー配列に適応してしまい、Deleteを押すつもりで常に上の｜キーを押してしまうようになりました。HHKBに切り替えると下の列を強制的に押さなければならず、非常にストレスを感じたため、両方ともBackSpaceに変更し、ほとんど使わない｜キーをF13の位置に移動しました。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-806c-acc9-fde5c028f922.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;次に、ControlとAltの位置を交換しました。これにより、MacでのCMD+C/V/T/Wなどの操作とWindowsでのControl+C/V/T/Wなどの操作で同じ指の動きが可能になります。&lt;/p&gt;
&lt;p&gt;最後に、WinキーとAltを交換（Winキーをキーボード左下に配置）することで、WindowsとMacでAlt（Opt）の位置を統一しました。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-80ae-98c6-ceb3f49fd02f.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;これで、スペースキーの左側のキー（WindowsではCtrl、MacではCMD）を押した後の操作が完全に同じになります。Ctrl/Cmd+Cでコピー、Ctrl/Cmd+Vでペースト、Ctrl/Cmd+Tで新規タブ、Ctrl/Cmd+Shift+Tで閉じたタブを復元など。&lt;/p&gt;
&lt;h2 id=&#34;その他のキー変更&#34;&gt;その他のキー変更&lt;/h2&gt;
&lt;p&gt;すでにHomeとEndのショートカットキーがあるため、キーボードの最右端にあるHomeとEndは不要です。そこで私は2つの操作を行いました。Homeキーをよく使うショートカットに変更し、Win + Vに設定しました。このショートカットはWindowsではクリップボード履歴を開き、MacではCmd + Opt + CにマッピングしてAlfredのクリップボード履歴ウィンドウを開くようにしています。&lt;/p&gt;
&lt;p&gt;HomeキーはM1マクロにマッピングし、コピー履歴を開きます。EndキーはWinLockに変更し、左下のWinキーを誤って押すのを防ぎます。現在はゲームプレイ時と同様にWinキーをロックし、慣れてから再度有効にする予定です。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-8011-957a-e63f205dd9e1.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;Win + V 打开复制历史&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-80e7-9c7b-fa95908c6985.webp&#39; alt=&#39;Win + V 打开复制历史&#39; title=&#39;Win + V 打开复制历史&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;Cmd + Opt + C 打开复制历史（Alfred）&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-80a0-a366-ecc5f5024d0a.webp&#39; alt=&#39;Cmd + Opt + C 打开复制历史（Alfred）&#39; title=&#39;Cmd + Opt + C 打开复制历史（Alfred）&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;美中不足&#34;&gt;美中不足&lt;/h2&gt;
&lt;p&gt;WindowsではAlt + Tabをマッピングできません。このキーの重要な役割はアプリケーションウィンドウの切り替えです。上記の設定後、この機能はスペースキーの左隣2番目のキー + Tabキーで実行されます。&lt;/p&gt;
&lt;p&gt;しかし、Macでアプリケーションを切り替える場合はCmd + Tabを使用します。&lt;/p&gt;
&lt;p&gt;したがって、私の設定ではアプリケーション切り替えキーのみが両システムでシステムレベルでマッピング不可となっていますが、他のキーはすべて同じ筋肉記憶で操作可能で、WindowsとMacのショートカット位置の違いを意識する必要はありません。&lt;/p&gt;
&lt;h2 id=&#34;後書き&#34;&gt;後書き&lt;/h2&gt;
&lt;p&gt;自分に合ったものが最善です。どのキー配置が優れているか議論する必要もありません。習慣の力は強力で、一度慣れてしまえばそれが最高の効率をもたらします。&lt;/p&gt;
&lt;p&gt;Happy Hackingをお祈りします！&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/input-more-efficiently/249800e8-7a61-8028-96b3-f2d7bb973946.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;</description>
            <pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/life/input-more-efficiently.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/life/input-more-efficiently.html</guid>
            
                <category>生活</category>
            
                <category>Apple</category>
            
                <category>经验</category>
            
                <category>总结</category>
            
                <category>VSCode</category>
            
                <category>工具</category>
            
                <category>踩坑</category>
            
                <category>细节</category>
            
                <category>Windows</category>
            
            
                <category>life</category>
            
        </item>
        
        <item>
            <title>アプリ開発の旅（一）：摩訶不思議なSwift</title>
            <description>&lt;h2 id=&#34;説明&#34;&gt;説明&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; なぜJavaScriptではないのかと聞かれることがありますが、それはスクリプト言語であり、型システムなどがなく、Swiftとは比較にならないからです。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;私はフロントエンド開発者で、C、Java、Python言語については入門レベルの理解しかありませんが、TypeScript（以下TS）の機能と使用に関しては上級レベル（自負）です。そのため、私が驚く点が、他の方々にとっては「ただの当たり前の言語機能」に思えたり、「TypeScriptの設計者は天才なのか？」と感じられるかもしれません。&lt;/p&gt;
&lt;p&gt;私はSwiftとTSの違いすべてに無理に驚くわけではありません。なぜなら、一部の違いはTS自身の不足によるものであり、またコンピュータ言語では一般的な設計（例えば数字をIntとDoubleで区別し、Number型だけにしないなど）もあるからです。驚くべきはJSの設計（結局1週間で急いで設計されたものです）であって、Swiftではありません。&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 私の考えでは、言語のルールや例外、予約語が多すぎる場合、それは良い言語とは言えません。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;この記事はSwiftの公式言語紹介の順番に沿って驚きを記述しており、驚かなかったり理解できない内容（例：&lt;code&gt;附加宏&lt;/code&gt;）は省略しています。&lt;/p&gt;
&lt;h2 id=&#34;基本知識&#34;&gt;基本知識&lt;/h2&gt;
&lt;h3 id=&#34;コメント&#34;&gt;コメント&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：XCodeには`/** */`ブロックコメントのショートカットがなく、`cmd + /`の行コメントしかありません。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;VSCodeのブロックコメントショートカットも押しにくく、&lt;code&gt;Alt + Shift + A&lt;/code&gt;です。この機能はあまり使われていないのでしょうか？&lt;/p&gt;
&lt;p&gt;もちろん、VSCodeとXCodeどちらも、&lt;code&gt;/**&lt;/code&gt;と入力してEnterを押すと、自動的にブロックコメントが生成されます。&lt;/p&gt;
&lt;h3 id=&#34;オプショナルバインディング&#34;&gt;オプショナルバインディング&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：デバッグ中に`if`文で常に`true`となる値をテスト用に書こうとしてもできません。`if`文のオプショナルバインディングは、必ずオプショナル型の値でなければなりません。&lt;/p&gt;&lt;/blockquote&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt; &amp;#123; &amp;#125; &lt;span class=&#34;hljs-comment&#34;&gt;// 错误！&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;こんな必要ある？&lt;/p&gt;
&lt;h2 id=&#34;コレクション型&#34;&gt;コレクション型&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：配列メソッドの中で、`sort` はその場でソートを行うのに対し、`sorted` は新しい配列を返します。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;一つの言語がフレームワークの仕事までこなすとは、さすがAppleのスタイルだ。これに類する驚きは他にもたくさんあるが、いちいち驚いている場合ではない。&lt;/p&gt;
&lt;h2 id=&#34;制御フロー&#34;&gt;制御フロー&lt;/h2&gt;
&lt;h3 id=&#34;if式&#34;&gt;if式&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：`if-else`で同じ変数に代入する場合に対処するため、`if`式の書き方が用意されています。同様に、`switch`にも式形式が存在します。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Swiftはやりすぎなところがある：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 平平无奇的写法&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; str: &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt; &amp;#123;&lt;br&gt;    str &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;小&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;30&lt;/span&gt; &amp;#123;&lt;br&gt;    str &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;大&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &amp;#123;&lt;br&gt;    str &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;中&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 简写法&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; str &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt; &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;小&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;30&lt;/span&gt; &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;大&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;中&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;switchのすごい判定&#34;&gt;Switchのすごい判定&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：switchには暗黙のフォールスルーがない&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;しかしこれは理解できるし、より合理的だ。普通の人が、わざわざ &lt;code&gt;break&lt;/code&gt; を書かずに case 1 から case 2 に自動的に進んでほしいと思うだろうか？&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：switchはオブジェクトの値を判定できる！&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;これは実際には &lt;code&gt;feature&lt;/code&gt; であり、直感的により合理的で、まさにプロフェッショナル向けだ。&lt;/p&gt;
&lt;p&gt;TSでは、&lt;code&gt;switch&lt;/code&gt;の&lt;code&gt;case&lt;/code&gt;文が全等(===)判定を使用するため、通常&lt;code&gt;switch&lt;/code&gt;の括弧内にオブジェクトを渡すことはない。オブジェクトは参照を判定するものであり、TSではオブジェクトの等価性を判定する必要がある場面は稀で、ましてや&lt;code&gt;switch&lt;/code&gt;文で判定することはまずない。&lt;/p&gt;
&lt;p&gt;しかしSwiftでは、&lt;code&gt;case&lt;/code&gt;文で判定する値を「キャプチャ」できる（正式名称は「パターン」と呼ばれる）：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; somePoint &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; (&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;hljs-comment&#34;&gt;// 一个平平无奇的元组罢了&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 我现在，开 始 判 断：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;switch&lt;/span&gt; somePoint &amp;#123;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;):&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(somePoint)&lt;/span&gt; 在原点&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;): &lt;span class=&#34;hljs-comment&#34;&gt;// 忽略第一个值&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(somePoint)&lt;/span&gt; 在 x 轴&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt;): &lt;span class=&#34;hljs-comment&#34;&gt;// 忽略第二个值&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(somePoint)&lt;/span&gt; 在 y 轴&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-operator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;hljs-operator&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-operator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;hljs-operator&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;): &lt;span class=&#34;hljs-comment&#34;&gt;// 判断元组的两个值是否分别在给定区间，在就匹配成功&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(somePoint)&lt;/span&gt; 在盒子内部&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;default&lt;/span&gt;:&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(somePoint)&lt;/span&gt; 在盒子外部&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 还可以值绑定！&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;switch&lt;/span&gt; somePoint &amp;#123;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; x, &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;): &lt;span class=&#34;hljs-comment&#34;&gt;// 匹配第二个值，捕获第一个值&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;x轴值：&lt;span class=&#34;hljs-subst&#34;&gt;\(x)&lt;/span&gt;&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; y): &lt;span class=&#34;hljs-comment&#34;&gt;// 匹配第一个值，捕获第二个值&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;y 轴值：&lt;span class=&#34;hljs-subst&#34;&gt;\(y)&lt;/span&gt;&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; (&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; x, &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; y): &lt;span class=&#34;hljs-comment&#34;&gt;// 兜底，因为 x 和 y 都是 let，还可以写作 case let (x, y)&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;\(x)&lt;/span&gt; 和 &lt;span class=&#34;hljs-subst&#34;&gt;\(y)&lt;/span&gt;&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 还可以加 where 限定：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; (x, y) &lt;span class=&#34;hljs-keyword&#34;&gt;where&lt;/span&gt; x &lt;span class=&#34;hljs-operator&#34;&gt;==&lt;/span&gt; y:&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;//还可以多个匹配&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;:&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;TSにおいても「複数マッチ」がサポートされていますが、Swiftのcaseにおける複数マッチとは全く異なることに注意が必要です。&lt;/p&gt;
&lt;p&gt;Swiftの複数マッチでは、カンマ区切りの内容のいずれかが一致すればcase文が実行されます。しかし、TSのカンマ区切りのマッチは、本質的に最後の項目のみにマッチします。これはTSにおけるカンマ区切りの文が最後の値のみを返すためです：&lt;/p&gt;
&lt;figure class=&#34;highlight typescript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs typescript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;switch&lt;/span&gt; (a) &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;:&lt;br&gt;  &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;)&lt;span class=&#34;hljs-comment&#34;&gt;// 此处不会执行，因为此 case 匹配 &amp;quot;b&amp;quot; &lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;関数&#34;&gt;関数&lt;/h2&gt;
&lt;h3 id=&#34;関数のラベル付き引数&#34;&gt;関数のラベル付き引数&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きのポイント：仮引数（ラベル付き引数）は同名でも良い？？？さらに規定（また制限が来た、参った）：可変引数の後ろの引数は必ず引数ラベルが必要（もし1つだけなら実引数が仮引数になる）省略できない。&lt;/p&gt;&lt;/blockquote&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 下面两个 a 标签参数，完全合法（因为是 label 无所谓）&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 而且 a b 后面的参数 a c（或者单独的一个参数）必须存在，不能用 _ 省略，&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;//  也可以理解，要不咋知道是第二个参数，而不是前面的可变参数来的？&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;a&lt;/span&gt; (&lt;span class=&#34;hljs-params&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt;..., &lt;span class=&#34;hljs-params&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;c&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; b.reduce(&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt;) &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt; c&lt;br&gt;&amp;#125;&lt;br&gt;a(a: &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;3&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;4&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;5&lt;/span&gt;, a: &lt;span class=&#34;hljs-number&#34;&gt;6&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;クロージャ&#34;&gt;クロージャ&lt;/h2&gt;
&lt;h3 id=&#34;クロージャのn種類の省略記法&#34;&gt;クロージャのN種類の省略記法&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：クロージャのシンタックスシュガーが多すぎてここでは全て列挙しませんが、最も衝撃的なのはたった1つの `&gt;` 記号だけで表現できる形式です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;このように書ける本質的な理由は、String型に &lt;code&gt;&amp;gt;&lt;/code&gt; という名前の関数が存在するからです。そうです、記号も関数になり得るのです！この点については後ほどさらに驚くべき内容を紹介します。&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; num &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; [&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;9&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;]&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; sortedNum &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; num.sroted(by: &lt;span class=&#34;hljs-operator&#34;&gt;&amp;gt;&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;本当に信じられない。&lt;/p&gt;
&lt;h3 id=&#34;returnの省略&#34;&gt;returnの省略&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きのポイント：「単一行のreturnは省略可能」と理解できるかもしれないが、「複数行でもreturnを省略できる」ことは絶対に理解できないでしょう&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;TypeScriptにおけるreturnの省略は、Swiftの通常の書き方と同じで、単一行のreturn省略：&lt;/p&gt;
&lt;figure class=&#34;highlight typescript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs typescript&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 省略写法&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;a&lt;/span&gt; = (&lt;span class=&#34;hljs-params&#34;&gt;&lt;/span&gt;) =&amp;gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 正常写法是：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;a&lt;/span&gt; = (&lt;span class=&#34;hljs-params&#34;&gt;&lt;/span&gt;) =&amp;gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;通常のSwift構文：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;a&lt;/span&gt;()-&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// -&amp;gt; 因为单行，所以省略了 return&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;しかし！SwiftUIでの書き方：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-type&#34;&gt;VStack&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-type&#34;&gt;Text&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;)&lt;br&gt; &lt;span class=&#34;hljs-type&#34;&gt;Text&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;驚くべきことに、これもトレーリングクロージャ関数です。&lt;code&gt;VStack&lt;/code&gt;は関数であり、クロージャパラメータが最後かつ唯一のパラメータとして渡されるため、&lt;code&gt;VStack&lt;/code&gt;の括弧を省略できます。しかし！ここでは2つの&lt;code&gt;Text&lt;/code&gt;関数呼び出しを返しているのに、&lt;code&gt;return&lt;/code&gt;が書かれていません。なぜでしょうか？&lt;/p&gt;
&lt;p&gt;それは&lt;code&gt;ViewBuilder&lt;/code&gt;を使用しているからです。この仕組みは後述する&lt;code&gt;resultBuilder&lt;/code&gt;と同じシンタックスシュガーです。&lt;/p&gt;
&lt;h3 id=&#34;自動クロージャ&#34;&gt;自動クロージャ&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：一見普通のクロージャ代入に過ぎないようですが、その遅延評価能力には驚かされました。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;自動クロージャについて最初に学んだ時、この例で「遅延評価」能力について説明されました：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; customersInLine &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; [&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Chris&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Alex&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Ewa&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Barry&amp;quot;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Daniella&amp;quot;&lt;/span&gt;]&lt;br&gt;&lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(customersInLine.count)&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 “5”&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; customerProvider &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &amp;#123; customersInLine.remove(at: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;) &amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(customersInLine.count)&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 ”5“&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Now serving &lt;span class=&#34;hljs-subst&#34;&gt;\(customerProvider())&lt;/span&gt;!&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 “Now serving Chris!”&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(customersInLine.count)&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 “4”&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;これはごく普通のクロージャーで、TSと同じくcustomerProvider変数がクロージャーに代入されているだけだと私は考えます。同じ実装をTSで書くとこうなります：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;customerProvider&lt;/span&gt; = (&lt;span class=&#34;hljs-params&#34;&gt;&lt;/span&gt;) =&amp;gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// 省略逻辑&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;そしてもちろん、それが呼び出されたときに初めてクロージャーのロジックが実行されます。これこそ遅延評価というものです！&lt;/p&gt;
&lt;p&gt;しかし、その遅延評価の真価が発揮されるのは、クロージャーが引数として渡される場合です。&lt;/p&gt;
&lt;p&gt;ごく普通の明示的なクロージャー呼び出しは、TSの呼び出し方法とほぼ同様で、クロージャーを引数として受け取り、書き方も中括弧の中に記述します：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// customersInLine 是 [&amp;quot;Alex&amp;quot;, &amp;quot;Ewa&amp;quot;, &amp;quot;Barry&amp;quot;, &amp;quot;Daniella&amp;quot;]&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;serve&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;customer&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;customerProvider&lt;/span&gt;: () -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;) &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Now serving &lt;span class=&#34;hljs-subst&#34;&gt;\(customerProvider())&lt;/span&gt;!&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;serve(customer: &amp;#123; customersInLine.remove(at: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;) &amp;#125; )&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 “Now serving Alex!”&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;しかし、&lt;code&gt;customerProvider&lt;/code&gt; を &lt;code&gt;@autoclosuer&lt;/code&gt; とマークすると状況が変わります。この場合、&lt;code&gt;serve&lt;/code&gt; 関数の呼び出しは次のように記述できます:&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// customersInLine 是 [&amp;quot;Ewa&amp;quot;, &amp;quot;Barry&amp;quot;, &amp;quot;Daniella&amp;quot;]&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;serve&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;customer&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;customerProvider&lt;/span&gt;: &lt;span class=&#34;hljs-keyword&#34;&gt;@autoclosure&lt;/span&gt; () -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;) &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;Now serving &lt;span class=&#34;hljs-subst&#34;&gt;\(customerProvider())&lt;/span&gt;!&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;serve(customer: customersInLine.remove(at: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;))&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 打印 “Now serving Ewa!”&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;最後の &lt;code&gt;serve&lt;/code&gt; 関数の呼び出しに注目してください。その引数 customer は文 &lt;code&gt;customersInLine.remove(at: 0)&lt;/code&gt; です。TSでは、どんな場合でも呼び出しスタックはまずこの値を評価してから &lt;code&gt;serve&lt;/code&gt; 関数を呼び出します。しかしSwiftでは、この書き方は上記の形式と単に見た目が異なるだけで、ロジックは同じです。つまり、まず &lt;code&gt;serve&lt;/code&gt; 関数が実行され、その後内部でこの文が実行されます（&lt;code&gt;customerProvider&lt;/code&gt; が呼び出された時点で）。これこそが噂の「遅延評価」というものでしょう。&lt;/p&gt;
&lt;p&gt;このようなケースを多く書いていると、以下のようなコードに頻繁に出くわすことになります：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;a(b.remove(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;))&lt;br&gt;c(d.add4())&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;ここでは、括弧内の文が先に実行されるのか、外側の関数が先なのか判断が難しい場合があります。そのため、Swiftの公式ドキュメントでも以下のように説明されています：&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 自動クロージャを過度に使用すると、コードの可読性が低下する可能性があります。コンテキストや関数名は、計算が延期されていることを明確に示す必要があります。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;本当に信じられない、推奨されていないなら最初から設計すべきじゃなかったのに！&lt;/p&gt;
&lt;h2 id=&#34;列挙型&#34;&gt;列挙型&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: 他の言語では単なる状態判断のためのオプション的な型に過ぎない列挙型が、Swiftでは最もよく使われる第一級の型であり、Structの機能を一部置き換えることができるなんて信じられますか？&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント2： 列挙型は値型です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;TypeScriptにおける列挙型はごく普通の「列挙型」にすぎず、単に値を列挙するだけで、主に状態マシンで状態を記述するために使用されます：&lt;/p&gt;
&lt;figure class=&#34;highlight typescript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs typescript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;enum&lt;/span&gt; A &amp;#123;&lt;br&gt; B = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;B&amp;quot;&lt;/span&gt;&lt;br&gt; C = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;もちろん、TSが提供する様々な機能には、実行時とコンパイル時の違いなどもありますが、ここでは触れません。TSでは、列挙型の代わりに完全にオブジェクトを使用することができます：&lt;/p&gt;
&lt;figure class=&#34;highlight typescript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs typescript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;enum&lt;/span&gt; A &amp;#123;&lt;br&gt;  B = &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;,&lt;br&gt;  C = &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;,&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; A = &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;B&lt;/span&gt;: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;,&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;C&lt;/span&gt;: &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;,&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt;;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;関連値&#34;&gt;関連値&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: Swiftのこの列挙型設計、一体何を考えてるの！&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Swiftにおいて、列挙型の重要性は最優先です。すべてのケースを列挙可能（&lt;code&gt;CaseIterable&lt;/code&gt;プロトコルに準拠が必要）、ケースを関数として扱い、呼び出し時に値を渡して列挙型インスタンスに処理させることができます。これを「関連値」と呼びます：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; b(&lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;, &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) &lt;span class=&#34;hljs-comment&#34;&gt;// 声明方式好像一个协议（也就是抽象类）&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; c(&lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;そして使用時に値を渡すことができます：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; a = A.&lt;span class=&#34;hljs-title function_&#34;&gt;b&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;1024&lt;/span&gt;, &lt;span class=&#34;hljs-number&#34;&gt;9527&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;列挙型が最もよく使われるのはswitch文の中です。驚くべきswitchと同様に驚くべきcaseを組み合わせて、次のように書くことができます：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;switch&lt;/span&gt; a &amp;#123;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; .&lt;span class=&#34;hljs-title function_&#34;&gt;b&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; d, &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; f):&lt;br&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;A.b 关联值为:\(d) 和 \(f)&amp;quot;&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; .&lt;span class=&#34;hljs-title function_&#34;&gt;c&lt;/span&gt;(g): &lt;span class=&#34;hljs-comment&#34;&gt;// 上面提到的另一种 switch case 写法&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;A.c:\(g)&amp;quot;&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;最初に見た時、正直かなり抽象的で、実際の使用場面も想像できませんでした（私自身そんなことをしたことがなかったので）。&lt;/p&gt;
&lt;h3 id=&#34;暗黙的な代入&#34;&gt;暗黙的な代入&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: 列挙型の型宣言は、列挙型自体の型（キーと値のペア）ではなく、ケースの型を宣言している。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Swiftにおける暗黙的な代入は、TypeScriptやその他のC系言語と同様で、最初の数字がnであれば、その後の値はn+1となります。&lt;/p&gt;
&lt;p&gt;しかしSwiftはさらに一歩進んでいて、宣言した型に基づいて暗黙的に値を代入します。デフォルトでは行われません。例えば：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt;: &lt;span class=&#34;hljs-title class_&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 声明了 Int 类型，所以隐式赋值了&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; b, c, d &lt;span class=&#34;hljs-comment&#34;&gt;// b c d 分别为 0 1 2(需要使用 A.b.rawValue 才能访问，这又是另一个震惊点了）&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;B&lt;/span&gt;: &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 声明了 String 类型，所以隐式赋值了&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;case&lt;/span&gt; bb, cc, dd &lt;span class=&#34;hljs-comment&#34;&gt;// bb cc dd分别为 &amp;quot;bb&amp;quot; &amp;quot;cc&amp;quot; &amp;quot;dd&amp;quot;&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;TSでは、Swiftで指定できるInt型（実際にはcaseの型を指す）さえ指定できず、enumの型（通常は&lt;code&gt;Record&lt;/code&gt;で別途定義されたキーバリューペア）しか指定できません。&lt;/p&gt;
&lt;h2 id=&#34;構造体とクラス&#34;&gt;構造体とクラス&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 衝撃の事実：構造体が値型だって？？？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;この一見しっかり者の構造体が、実は値型（パフォーマンス最適化のために&lt;code&gt;Immutable&lt;/code&gt;の仕組みを使用）だったとは：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;a&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c: &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;波括弧付きのもの、どう見ても値には見えない！信じられない！驚き！&lt;/p&gt;
&lt;h2 id=&#34;プロパティ&#34;&gt;プロパティ&lt;/h2&gt;
&lt;h3 id=&#34;様々なxxプロパティ-ラッパー-オブザーバー&#34;&gt;様々なxxプロパティ/ラッパー/オブザーバー&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：Swiftがやりすぎている。計算プロパティ、ストアドプロパティ、プロパティラッパー（TSにもある）、プロパティオブザーバー（TSにもあり、ラッパーと一緒）といった概念は、通常フレームワークが提供するものだ。例えばVueの`computed`や`watch`など。しかしSwiftはStructとクラスの中でこれらを自前で実装している。信じられない！&lt;/p&gt;&lt;/blockquote&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 存储属性，直接有值，在 struct 实例化的时候就确定了&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 一个只读计算属性，不存储值，因为单行，return 可以省略&lt;/span&gt;&lt;br&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;なお、属性ラッパーはグローバル変数には使用できません。&lt;/p&gt;
&lt;h2 id=&#34;サブスクリプト&#34;&gt;サブスクリプト&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: これについては特に言うことはありません。「サブスクリプト」という概念自体が既に驚きで、コレクション、リスト、ディクショナリの要素にアクセスするためのショートカットを提供しています。さらに、サブスクリプトは関数のように複数の値を渡すこともできます。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;基本的に、サブスクリプトの呼び出し方法は、データ構造（前述のコレクション、リスト、ディクショナリ）に対する関数呼び出しで値をアクセスすると考えられますが、違いは関数呼び出しが &lt;code&gt;()&lt;/code&gt; を使用するのに対し、サブスクリプトは &lt;code&gt;[]&lt;/code&gt; を使用することです。&lt;/p&gt;
&lt;h2 id=&#34;継承&#34;&gt;継承&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: これまでのすべての驚きポイントと同様に、Swiftはさまざまな目的や効果を実現するために、あたかも随意にキーワードを追加しているかのようです。そのため、継承に関連する予約語（もちろん、「予約語」と呼べるものではありません。Swiftでは予約語もすべて使用可能で、バッククォートで囲めば良いのです。これについては後ほど驚きポイントとして取り上げます）が数多く存在します。例えば: `final`、`override`、`open`、`required` など。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;初期化プロセス&#34;&gt;初期化プロセス&lt;/h2&gt;
&lt;h3 id=&#34;structのメンバーワイズイニシャライザ&#34;&gt;Structのメンバーワイズイニシャライザ&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: Structは値型であるため、従来のClassのイニシャライザルールとは初期化時に違いがあります。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;本来、StructとClassはどちらもごく普通のデータ構造で、TSのClassと何ら変わりません。しかし、Swiftはここでも一風変わったことをしています。&lt;/p&gt;
&lt;p&gt;Structは値型であるため、特別な点として「メンバーワイズイニシャライザ」と呼ばれる初期化形式があります。これは、Structに &lt;code&gt;init&lt;/code&gt; が全く定義されていない場合、そのプロパティを初期化するために引数を渡す形式でinitでき、明示的に記述する必要がないというものです。&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 此 Struct 没有 init，因此适用逐一成员构造器&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123; &lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 上述效果等同于：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;a&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;, &lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; a&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; b&lt;br&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 上面两个都可以这么用：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;(a: &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;, b: &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;)&lt;br&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;しかし、このルールはClassには適用されません。Classは明示的にinitコンストラクタメソッドを持ち、プロパティを初期化する必要があります。&lt;/p&gt;
&lt;h3 id=&#34;クラスの指定イニシャライザとコンビニエンスイニシャライザ&#34;&gt;クラスの指定イニシャライザとコンビニエンスイニシャライザ&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: え？イニシャライザには2種類あるの？？？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;クラスの指定イニシャライザは、TSにおける通常の&lt;code&gt;construct&lt;/code&gt;と同じ役割を持つ&lt;code&gt;init&lt;/code&gt;メソッドです。しかし、そのコンビニエンスイニシャライザは…initの前に&lt;code&gt;convenience&lt;/code&gt;キーワードを付ける（また来た！）ものです:&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;convenience&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;() &amp;#123;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;実はここでSwiftのドキュメントは、なぜ便利イニシャライザが必要なのかを明確に読者に伝えず、直接クラスの初期化、継承プロセスとイニシャライザのデリゲーションについて説明しています。ここで初心者の方々に、なぜ便利イニシャライザというものが存在するのかを説明します。とてもシンプルな理由です：&lt;code&gt;クラス内の複数の指定イニシャライザは互いに呼び出し合うことが許されていません。&lt;/code&gt;これだけの理由です。呼び出したくてたまらない？初期化プロセスを簡素化したい？それなら便利イニシャライザを使いなさい！&lt;/p&gt;
&lt;p&gt;通常の書き方：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c: &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;, &lt;span class=&#34;hljs-params&#34;&gt;c&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;String&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; b&lt;br&gt; &amp;#125;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;() &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.c &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;UnKnown&amp;quot;&lt;/span&gt;&lt;br&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;上記のように、self.b を2回書くのは面倒だと感じませんか？そこで、2番目の &lt;code&gt;init()&lt;/code&gt; では、このようにしたいと考えています：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;() &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.&lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;(b: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, c: &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;UnKnown&amp;quot;&lt;/span&gt;)	&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;コンパイラエラーが報告されました：&lt;code&gt;Designated initializer for &#39;A&#39; cannot delegate (with &#39;self.init&#39;); did you mean this to be a convenience initializer?&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;この場合、convenienceイニシャライザを使用する必要があります：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;converience &lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;() &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;self&lt;/span&gt;.&lt;span class=&#34;hljs-keyword&#34;&gt;init&lt;/span&gt;(b: &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;, c: &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;UnKnown&amp;quot;&lt;/span&gt;)	&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;「便利」が目的です～&lt;/p&gt;
&lt;h3 id=&#34;失敗可能イニシャライザ&#34;&gt;失敗可能イニシャライザ&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: イニシャライザが失敗することもある？&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;実は、失敗可能イニシャライザとは、初期化プロセス（init関数の呼び出しプロセス）でエラーが発生する可能性があるものを指します。&lt;/p&gt;
&lt;p&gt;したがって、イニシャライザがエラーを投げる場合、TSのように外側で&lt;code&gt;try-catch&lt;/code&gt;する必要はなく、直接明示すればよいです。方法は&lt;code&gt;init&lt;/code&gt;の後に疑問符を付けて&lt;code&gt;init?&lt;/code&gt;とし、エラーが発生する可能性のある場所で&lt;code&gt;nil&lt;/code&gt;を返し、インスタンス化時に&lt;code&gt;nil&lt;/code&gt;かどうかを判断するだけです。&lt;/p&gt;
&lt;p&gt;Swiftでは通常のイニシャライザは値を返しません。これはTSと同じです——ただしTSのイニシャライザは値を返すことができ、返される値がオブジェクト型の場合、&lt;code&gt;this&lt;/code&gt;オブジェクトを置き換えます。これはさらに驚きかもしれません。&lt;/p&gt;
&lt;h2 id=&#34;オプショナルチェーン&#34;&gt;オプショナルチェーン&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント: Q: どのような場合に関数に()を書いているのに実行されない？A: オプショナルチェーンのシナリオです。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;余計な説明は抜きにして、例を見てみましょう:&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;A&lt;/span&gt;() -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-built_in&#34;&gt;print&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;)&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;B&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c: &lt;span class=&#34;hljs-type&#34;&gt;C&lt;/span&gt;?&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;C&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; d: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;?&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; d &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;B&lt;/span&gt;()&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 震惊的事情发生了：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 这里，A 函数未执行，不会打印 OK，赋值也不会成功，因为 c 是 nil，这个语句返回 nil（通常 Swift 的赋值语句都返回 Void 的，也就是空元组）&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 返回 nil 意味着你可以使用 if-let 语句判断&lt;/span&gt;&lt;br&gt;d.c&lt;span class=&#34;hljs-operator&#34;&gt;?&lt;/span&gt;.d &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;()&lt;br&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;エラー処理&#34;&gt;エラー処理&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：列挙型と同様に、Swiftのtry-catch（実際はdo-catch）の設計は非常に複雑です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;catch文は任意のエラーをキャッチできるだけでなく、特定のエラータイプもキャッチ可能で、isを使用したりswitch文のように複数のcatch分岐でマッチングが行えます。これは驚きです：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;do&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;try&lt;/span&gt; someError()&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;ErrorA&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// xxx&lt;/span&gt;&lt;br&gt;&amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;ErrorB&lt;/span&gt;, &lt;span class=&#34;hljs-type&#34;&gt;ErrorC&lt;/span&gt;, &lt;span class=&#34;hljs-type&#34;&gt;ErrorD&lt;/span&gt;.a &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// xxx&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&#34;並行処理&#34;&gt;並行処理&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：ドキュメントを読んでいた時、最初は `withTaskGroup` が Group Task を行う組み込みメソッドだとは気づきませんでした。。。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;await&lt;/code&gt; の使い方は TS の &lt;code&gt;await&lt;/code&gt; と全く同じで、快適です！&lt;/p&gt;
&lt;h2 id=&#34;拡張機能&#34;&gt;拡張機能&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：拡張機能はおそらく Swift で最も強力な設計です。組み込みオブジェクトでもサードパーティ製でも、どんなオブジェクトでも、自由に、低コストで、複雑な宣言やキーワードを一切必要とせずに拡張できます。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;TS では既存のクラスを拡張する場合、プロトタイプチェーンを操作し、オブジェクトの this をそのクラスに向ける必要があります。&lt;/p&gt;
&lt;p&gt;しかし Swift では、単に &lt;code&gt;extension&lt;/code&gt; を書くだけで、好きなメソッドやプロパティを自由に追加できます。それらの &lt;code&gt;this&lt;/code&gt; はインスタンスを指すか、拡張型（つまり静的）メソッドやプロパティになります。&lt;/p&gt;
&lt;p&gt;まさに圧倒的な自由度です。&lt;/p&gt;
&lt;h2 id=&#34;プロトコル&#34;&gt;プロトコル&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：プロトコルは Struct の抽象化問題を解決するために導入されたと思います。どの言語でもクラス自体は継承可能（言い切りすぎかもしれませんが）なので、余計な「プロトコル」を実装する必要はなく、抽象クラスで十分です。ただ副次的に、Swift はクラスの単一継承を制限すると同時に、プロトコルをクラス、Struct、列挙型のすべてで活用できるようにしました。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;これ以上言うことはありません。言いたいことは上記に尽きます。&lt;/p&gt;
&lt;h2 id=&#34;ジェネリクス&#34;&gt;ジェネリクス&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：ジェネリクスには「関連型」という概念があり、これは宣言時に付与するジェネリクスと同様の役割ですが、より強力です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Swift のジェネリクス関連型は次のようなものです：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Container&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;associatedtype&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;mutating&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;append&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;item&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt;)&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; count: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-keyword&#34;&gt;get&lt;/span&gt; &amp;#125;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;subscript&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;i&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-keyword&#34;&gt;get&lt;/span&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;なぜこのように設計されていないのか：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Container&lt;/span&gt;&amp;lt;&lt;span class=&#34;hljs-title class_&#34;&gt;Item&lt;/span&gt;&amp;gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;mutating&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;append&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;item&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt;)&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; count: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-keyword&#34;&gt;get&lt;/span&gt; &amp;#125;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;subscript&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;i&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-keyword&#34;&gt;get&lt;/span&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;おそらく、この項目が非常に長くなり、エレガントでなくなる可能性があるためでしょう。例えば：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;SuffixableContainer&lt;/span&gt;: &lt;span class=&#34;hljs-title class_&#34;&gt;Container&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;associatedtype&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Suffix&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;SuffixableContainer&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Suffix&lt;/span&gt;.&lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt; &lt;span class=&#34;hljs-operator&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Item&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;suffix&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;size&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Suffix&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;名前の後ろに書くと、ジェネリック宣言が頻繁に画面からはみ出してしまい、非常に扱いづらい。&lt;/p&gt;
&lt;h2 id=&#34;不透明型とカプセル化プロトコル&#34;&gt;不透明型とカプセル化プロトコル&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚くべき点：コンパイラには型が何であるかを知らせつつ、呼び出し側には具体的な型を知らせず、ただそれが特定のプロトコルに準拠していることだけを知らせる効果を実現できます。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;基本的に、不透明型とカプセル化プロトコルが実現しようとしている効果は、一方で呼び出し側に実装詳細を隠蔽しつつ、コードをリファクタリングする際に多くの変更を必要としないようにすることです。例えば：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Shape&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;area&lt;/span&gt;() -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Circle&lt;/span&gt;: &lt;span class=&#34;hljs-title class_&#34;&gt;Shape&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; radius: &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;area&lt;/span&gt;() -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Double&lt;/span&gt; &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; .pi &lt;span class=&#34;hljs-operator&#34;&gt;*&lt;/span&gt; radius &lt;span class=&#34;hljs-operator&#34;&gt;*&lt;/span&gt; radius&lt;br&gt;    &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;makeShape&lt;/span&gt;() -&amp;gt; &lt;span class=&#34;hljs-keyword&#34;&gt;some&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Shape&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Circle&lt;/span&gt;(radius: &lt;span class=&#34;hljs-number&#34;&gt;5&lt;/span&gt;)&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;ここで、&lt;code&gt;makeShape&lt;/code&gt;が返す型は、&lt;code&gt;Shape&lt;/code&gt;プロトコルに準拠する任意の型であればよく、明示的に&lt;code&gt;Circle&lt;/code&gt;型を返す必要はありません。このようにすることで、後から&lt;code&gt;Shape&lt;/code&gt;に準拠する新しい&lt;code&gt;Struct&lt;/code&gt;を追加しても、この関数はそれを返すことができます（これはSwiftUIでよく使われる方法でもあります。例えば&lt;code&gt;some View&lt;/code&gt;など）。&lt;/p&gt;
&lt;h2 id=&#34;メモリ安全性&#34;&gt;メモリ安全性&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きのポイント：Swiftは値の参照渡しが可能なため、同じメモリ領域への同時読み書きが発生する可能性があります（これは理にかなっていますよね？）&lt;/p&gt;&lt;/blockquote&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;add&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;hljs-keyword&#34;&gt;inout&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) &amp;#123;&lt;br&gt;    b &lt;span class=&#34;hljs-operator&#34;&gt;+=&lt;/span&gt; a&lt;br&gt;&amp;#125;&lt;br&gt;add(&lt;span class=&#34;hljs-operator&#34;&gt;&amp;amp;&lt;/span&gt;a)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;上記の実行はエラーを発生させますが、コンパイラは警告を出しません。このようなケースは多く存在するため、特に注意が必要です。TSには参照渡しの概念が存在しないため、このような問題は発生せず、簡単です～&lt;/p&gt;
&lt;h2 id=&#34;高度な演算子&#34;&gt;高度な演算子&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きのポイント: 記号を関数名として使用した関数を再定義/カスタマイズすることで、同じクラスや構造体のインスタンス間で相互操作を実現できます。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;例を挙げます:&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;+&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;left&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;, &lt;span class=&#34;hljs-params&#34;&gt;right&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;(b: left.b &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt; right.b, c: left.c &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt; right.c)&lt;br&gt; &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 然后你就可以&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;()&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;()&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;let&lt;/span&gt; c &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt; b &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 是的你没看错，struct 实例可以相加！&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;このデザインは素晴らしい、どうして思いつかなかったんだろう。すごいすごい。&lt;/p&gt;
&lt;p&gt;注意が必要なのは、演算子メソッドには独自の属性があることです。例えば、&lt;code&gt;+&lt;/code&gt; は二項演算子であり中置演算子でもあるため、2つの関数を受け取ります。&lt;code&gt;-&lt;/code&gt; は中置演算子（二項演算子）にも、前置演算子（単項演算子、&lt;code&gt;func&lt;/code&gt; の前に &lt;code&gt;prefix&lt;/code&gt; を追加する必要あり）にもなるため、オーバーロード可能です。&lt;/p&gt;
&lt;p&gt;しかしSwiftでは、代入演算子 &lt;code&gt;=&lt;/code&gt; はオーバーロードできず、三項条件演算子（&lt;code&gt;a ? b : c&lt;/code&gt;）も同様にオーバーロード不可と規定されています。&lt;/p&gt;
&lt;p&gt;この演算子は非常に一般的で、任意のSwift組み込みオブジェクト/Foundationオブジェクトにおいて、&lt;code&gt;==&lt;/code&gt; のような等価判定の演算子関数を見かけることができます。&lt;/p&gt;
&lt;p&gt;さらに、独自の演算子を実装することさえ可能です！&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 需要先声明，这是一个操作符，因为有两个值在操作符，所以这是个中缀操作符(infix)&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;infix&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;operator&lt;/span&gt; &lt;span class=&#34;hljs-title&#34;&gt;+++++++&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 然后扩展一下整数类型&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;extension&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Int&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;+++++++&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;left&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;, &lt;span class=&#34;hljs-params&#34;&gt;right&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; (left &lt;span class=&#34;hljs-operator&#34;&gt;+&lt;/span&gt; right) &lt;span class=&#34;hljs-operator&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 因为有 7 个 + 号，所以我写了乘以 7&lt;/span&gt;&lt;br&gt;    &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 这么用：&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;hljs-operator&#34;&gt;+++++++&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;7&lt;/span&gt; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 63&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;すごい。&lt;/p&gt;
&lt;h3 id=&#34;結果ビルダー&#34;&gt;結果ビルダー&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きポイント：Swiftは「エレガントさ」と「再利用性」のために手段を選ばない。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;以下のコードを見栄え良くするために、Swiftは&lt;code&gt;@resultBuilder&lt;/code&gt;という魔法のようなものを「発明」しました。例：&lt;/p&gt;
&lt;p&gt;通常の書き方：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; a: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 这里会有一个三元判断&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;(a: a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;gt;&lt;/span&gt; b &lt;span class=&#34;hljs-operator&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;666&lt;/span&gt; : &lt;span class=&#34;hljs-number&#34;&gt;999&lt;/span&gt; )&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Swiftは、上記の三項演算子による判定が煩雑で、複雑な条件分岐の場合にはコードが長くなり可読性が低下すると指摘し、よりエレガントな解決策を求めました。そこで生まれたのが（私の理解が正しければ）結果ビルダーです：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;@resultBuilder&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;BBuilder&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;buildBlock&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-comment&#34;&gt;// 对应 if/else 分支的执行结果&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; b&lt;br&gt;    &amp;#125;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;buildEither&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;aaa&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-comment&#34;&gt;// 对应 if 分支&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; aaa&lt;br&gt;    &amp;#125;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;buildEither&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;bbb&lt;/span&gt;: &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt; &amp;#123; &lt;span class=&#34;hljs-comment&#34;&gt;// 对应 else 分支&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; bbb&lt;br&gt;    &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;そして、上記の &lt;code&gt;c&lt;/code&gt; 変数に次のように値を代入します：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;BB&lt;/span&gt;(&lt;span class=&#34;hljs-meta&#34;&gt;@BBuilder&lt;/span&gt; &lt;span class=&#34;hljs-params&#34;&gt;b&lt;/span&gt;: () -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;Int&lt;/span&gt;) -&amp;gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;A&lt;/span&gt;(a: b())&lt;br&gt;&amp;#125;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 终于等到 c 了，这里的 c 和最开始的 c 完全一样&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;var&lt;/span&gt; c &lt;span class=&#34;hljs-operator&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;hljs-type&#34;&gt;BB&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;hljs-operator&#34;&gt;&amp;gt;&lt;/span&gt; b &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;666&lt;/span&gt;&lt;br&gt;    &amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-number&#34;&gt;999&lt;/span&gt;&lt;br&gt;    &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;再利用、エレガント、効率的、最高！&lt;/p&gt;
&lt;h2 id=&#34;字句構造&#34;&gt;字句構造&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 驚きのポイント：Swiftには予約語が非常に多いにもかかわらず、予約語を識別子として使用することが許可されています。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;方法は、バッククォートで囲むだけです：&lt;/p&gt;
&lt;figure class=&#34;highlight swift&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs swift&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;`func`&lt;/span&gt;() &amp;#123;&amp;#125; &lt;span class=&#34;hljs-comment&#34;&gt;// &amp;lt;- 一个叫做 `func` 的函数&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;// 调用也是 &lt;/span&gt;&lt;br&gt;`func`()&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;しかし、キーワードを除けば、&lt;code&gt;x&lt;/code&gt; と x は同じ変数です。&lt;/p&gt;
</description>
            <pubDate>Thu, 27 Mar 2025 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/app-dev-journey-swift.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/app-dev-journey-swift.html</guid>
            
                <category>Apple</category>
            
                <category>苹果</category>
            
                <category>初体验</category>
            
                <category>教程</category>
            
                <category>技巧</category>
            
                <category>技术</category>
            
                <category>Swift</category>
            
                <category>全栈</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>CusorでiOSアプリを開発しリアルタイムでプレビューする方法</title>
            <description>&lt;p&gt;本記事は著者の拡張版であり、著者の原文は以下を参照してください：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.imjp.uk/fxxk-xcode&#34; target=&#34;_blank&#34;&gt; 在 Cursor 打造高效 iOS 开发环境： AI 编程 + 实时预览完整指南&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;私がここで追加の補足をするのは、このチュートリアルを見た際、XCodeとiOS開発について全く知識がなかったため、いくつか回り道をしたからです。そのため、ここに記録を残します。&lt;/p&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 本記事は主に原文への補足ですので、まず原文をご確認ください。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id=&#34;「swiftプラグインとcodelldbプラグインのインストール」への補足：&#34;&gt;「SwiftプラグインとCodeLLDBプラグインのインストール」への補足：&lt;/h3&gt;
&lt;p&gt;ここで記載されているSwiftプラグインは既に古くなっています。最新のプラグインを使用する必要があり、プラグインマーケットで「&lt;strong&gt;Swift Programming Language&lt;/strong&gt;」を検索してください。&lt;/p&gt;
&lt;h3 id=&#34;「ホットリロードの設定」のステップ2への補足：&#34;&gt;「&lt;strong&gt;ホットリロードの設定&lt;/strong&gt;」のステップ2への補足：&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; プロジェクトの対応するTargetの設定 -&gt; Build Settings -&gt; 「Other Linker Flags」を検索し、それぞれ「-Xlinker」と「-interposable」を追加します。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;ここで注意すべきは、両方を同時に追加することです。つまり&lt;code&gt;-Xlinker -interposable&lt;/code&gt;をコピーして下図のように貼り付けてください：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/use-cursor-develop-ios/197800e8-7a61-8012-b016-c6caf5e72435.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;新しいファイルを追加した後、source-kitがファイルを見つけられないというエラーが発生する問題&#34;&gt;新しいファイルを追加した後、Source Kitがファイルを見つけられないというエラーが発生する問題&lt;/h3&gt;
&lt;p&gt;Xcode-Build-Serverを使用して、原文で言及されているコマンドを再度実行する必要があります：&lt;/p&gt;
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs bash&#34;&gt;// 然后在项目根目录下根据你的项目文件类型执行对应的命令:&lt;br&gt;xcode-build-server config -workspace *.xcworkspace -scheme &amp;lt;XXX&amp;gt; &lt;br&gt;xcode-build-server config -project *.xcodeproj -scheme &amp;lt;XXX&amp;gt;&lt;br&gt;&lt;br&gt;//例如你用的是 exampleProject.xcodeproj：&lt;br&gt;xcode-build-server config -project exampleProject.xcodeproj -scheme exampleProject&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;swiftuiのデバッグ時に変更がリアルタイムでプレビューされない問題：&#34;&gt;SwiftUIのデバッグ時に変更がリアルタイムでプレビューされない問題：&lt;/h3&gt;
&lt;p&gt;一部のViewModifierを追加/変更した場合、確かにリアルタイム更新されませんが、Text内のStringのような変更であれば通常問題ありません。理由は私もわかりません。&lt;/p&gt;
</description>
            <pubDate>Tue, 11 Feb 2025 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/use-cursor-develop-ios.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/use-cursor-develop-ios.html</guid>
            
                <category>Apple</category>
            
                <category>教程</category>
            
                <category>技巧</category>
            
                <category>AI</category>
            
                <category>技术</category>
            
                <category>XCode</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>JekyllからHexoへの移行時の問題記録</title>
            <description>&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;私はフロントエンド開発者であるため、Rubyのような他のスクリプト言語には詳しくありません。ブログを書き始めた当初はGithub Pagesをブログプラットフォームとして使用し、デフォルトでJekllyフレームワークが採用されていました。コンテンツがフレームワークよりも重要だと考え、そのまま使い続け、気がつけば10年が経っていました。&lt;/p&gt;
&lt;p&gt;その間いくつかのテーマを変更しましたが、最終的にHuxが提供するテーマに落ち着きました。シンプルで洗練されており、しかもオープンソースだったからです：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://huangxuan.me/&#34; target=&#34;_blank&#34;&gt; 黄玄的博客 | Hux Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このテーマに対し、右サイドバーのカスタマイズ、データのカスタマイズ、Notionをデータソースとして使用したレンダリングなど、多くのカスタマイズを施しました。&lt;/p&gt;
&lt;p&gt;しかし、AppleのMシリーズチップの登場により、IntelとAppleチップ間でのRubyの差異に対処することがますます困難になりました。例えば、ビルド時にx86アーキテクチャの命令を特別に使用しなければ偶然正しくビルドできる程度で、しかも依存関係を一切変更できない状況でした：&lt;/p&gt;
&lt;figure class=&#34;highlight bash&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs bash&#34;&gt;&lt;span class=&#34;hljs-built_in&#34;&gt;arch&lt;/span&gt; -x86_64 bundle &lt;span class=&#34;hljs-built_in&#34;&gt;exec&lt;/span&gt; jekyll server --trace --config=_config.dev.yml --ssl-key local.xheldon.cn.key --ssl-cert local.xheldon.cn.pem&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;このため、フレームワークを早急に変更しなければ、将来的にブログを全く公開できなくなる可能性があると気づきました。&lt;/p&gt;
&lt;h2 id=&#34;技術選定&#34;&gt;技術選定&lt;/h2&gt;
&lt;p&gt;このセクションには特に述べるべきことはありません。基本的に、HexoはJekyllのJavaScript実装と考えることができます。多くの概念が95%同じであるため、移行に苦労することはありません。&lt;/p&gt;
&lt;p&gt;さらに重要なことに、HexoにもHuxのブログテーマテンプレートを作成している人がいたため、私はそれをそのまま使用することにしました。この過程で簡単に手順を記録しておきます。&lt;/p&gt;
&lt;h2 id=&#34;移行プロセス&#34;&gt;移行プロセス&lt;/h2&gt;
&lt;h3 id=&#34;プラグイン移行&#34;&gt;プラグイン移行&lt;/h3&gt;
&lt;p&gt;これは比較的簡単でした。Jekyllのプラグインは、Hexoではヘルパー関数として実装しました。以下はNotionからのBookmarkタグを処理する関数です（パスは&lt;code&gt;_plugins/add-attribute.rb&lt;/code&gt;）：&lt;/p&gt;
&lt;figure class=&#34;highlight ruby&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs ruby&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;RenderBookMarkBlock&lt;/span&gt; &amp;lt; &lt;span class=&#34;hljs-title class_ inherited__&#34;&gt;Liquid::Block&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;initialize&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;tag_name, attr, tokens&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-comment&#34;&gt;# 普通的链接没有 yid 和 bid&lt;/span&gt;&lt;br&gt;            attrs = attr.scan(&lt;span class=&#34;hljs-regexp&#34;&gt;/url\=\&amp;quot;(.*)\&amp;quot;\stitle\=\&amp;quot;(.*)\&amp;quot;\simg\=\&amp;quot;(.*)\&amp;quot;\syid\=\&amp;quot;(.*)\&amp;quot;\sbid\=\&amp;quot;(.*)\&amp;quot;/&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; !attrs.empty?&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;3&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;4&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt; = &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;.empty? ? &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; : (&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;)[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;].upcase&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@error&lt;/span&gt; = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt;&lt;br&gt;                attrs = attr.scan(&lt;span class=&#34;hljs-regexp&#34;&gt;/url\=\&amp;quot;(.*)\&amp;quot;\stitle\=\&amp;quot;(.*)\&amp;quot;\simg\=\&amp;quot;(.*)\&amp;quot;/&lt;/span&gt;)&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt; = &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;.empty? ? &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt; : (&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;)[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;].upcase&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@error&lt;/span&gt; = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;render&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;context&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable&#34;&gt;@desc&lt;/span&gt; = &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; !&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;.&lt;span class=&#34;hljs-literal&#34;&gt;nil&lt;/span&gt;? &amp;amp;&amp;amp; !&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;.empty?&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;https://www.youtube.com/embed/&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;&amp;#125;&lt;/span&gt;?rel=0&amp;#x27; title=&amp;#x27;YouTube video player&amp;#x27; frameborder=&amp;#x27;0&amp;#x27; allow=&amp;#x27;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;elsif&lt;/span&gt; !&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;.&lt;span class=&#34;hljs-literal&#34;&gt;nil&lt;/span&gt;? &amp;amp;&amp;amp; !&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;.empty?&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27; style=&amp;#x27;border-bottom: 1px solid #ddd;&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;//player.bilibili.com/player.html?bvid=&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;amp;high_quality=1&amp;amp;as_wide=1&amp;#x27; scrolling=&amp;#x27;no&amp;#x27; border=&amp;#x27;0&amp;#x27; frameborder=&amp;#x27;no&amp;#x27; framespacing=&amp;#x27;0&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt;&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p&amp;gt;&amp;lt;a class=&amp;#x27;link-bookmark&amp;#x27; href=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; target=&amp;#x27;_blank&amp;#x27;&amp;gt;&amp;lt;span data-bookmark-img=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; data-bookmark-title=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27;&amp;gt;&amp;lt;img src=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27;/&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@desc&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-title class_&#34;&gt;Liquid&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:Template&lt;/span&gt;.register_tag(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;render_bookmark&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:RenderBookMarkBlock&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;一方、Hexoでは以下のように記述しました（パスは&lt;code&gt;scripts/liquid.js&lt;/code&gt;）：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;tag&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;render_bookmark&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;args, content&lt;/span&gt;) &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; [url, title, img, yid, bid] = args.&lt;span class=&#34;hljs-title function_&#34;&gt;map&lt;/span&gt;(getValue);&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; firstChar = title ? title[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;].&lt;span class=&#34;hljs-title function_&#34;&gt;toUpperCase&lt;/span&gt;() : &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; strip_html = hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;helper&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;get&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;strip_html&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;bind&lt;/span&gt;(hexo);&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; trim = hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;helper&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;get&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;trim&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;bind&lt;/span&gt;(hexo);&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (yid) &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;https://www.youtube.com/embed/&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;yid&amp;#125;&lt;/span&gt;?rel=0&amp;#x27; title=&amp;#x27;YouTube video player&amp;#x27; frameborder=&amp;#x27;0&amp;#x27; allow=&amp;#x27;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;&lt;br&gt;    &amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (bid) &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27; style=&amp;#x27;border-bottom: 1px solid #ddd;&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;//player.bilibili.com/player.html?bvid=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;bid&amp;#125;&lt;/span&gt;&amp;amp;high_quality=1&amp;amp;as_wide=1&amp;#x27; scrolling=&amp;#x27;no&amp;#x27; border=&amp;#x27;0&amp;#x27; frameborder=&amp;#x27;no&amp;#x27; framespacing=&amp;#x27;0&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;;&lt;br&gt;    &amp;#125;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&amp;lt;p&amp;gt;&amp;lt;a class=&amp;#x27;link-bookmark&amp;#x27; href=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;url&amp;#125;&lt;/span&gt;&amp;#x27; target=&amp;#x27;_blank&amp;#x27;&amp;gt;&amp;lt;span data-bookmark-img=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;img&amp;#125;&lt;/span&gt;&amp;#x27; data-bookmark-title=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;firstChar&amp;#125;&lt;/span&gt;&amp;#x27;&amp;gt;&amp;lt;img src=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;img&amp;#125;&lt;/span&gt;&amp;#x27;/&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;lt;span&amp;gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;title&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;strip_html(trim(content))&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;url&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;`&lt;/span&gt;;&lt;br&gt;&amp;#125;, &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;ends&lt;/span&gt;: &lt;span class=&#34;hljs-literal&#34;&gt;true&lt;/span&gt;,&lt;br&gt;&amp;#125;);&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;permalink問題&#34;&gt;Permalink問題&lt;/h3&gt;
&lt;p&gt;理由はわかりませんが、Hexoで&lt;code&gt;:category/:name.html&lt;/code&gt;を設定しているにもかかわらず、生成されるのは&lt;code&gt;life/2024-life-xxx.html&lt;/code&gt;（&lt;code&gt;-&lt;/code&gt;ディレクトリ区切りを使用）で、本来期待されるのは&lt;code&gt;life/xxx.html&lt;/code&gt;でした。ソースコード&lt;code&gt;name&lt;/code&gt;を見ると、&lt;code&gt;slug&lt;/code&gt;が使用されており、&lt;code&gt;basename&lt;/code&gt;ですが、&lt;code&gt;slug&lt;/code&gt;の生成ロジックはfolderパスに基づいてハイフンが追加されるため、手動でファイル名を修正するしかありませんでした。Jekyllでは、ファイル名の前の日付形式（例：&lt;a href=&#34;http://2024-02-12-xxx.md&#34;&gt;2024-02-12-xxx.md&lt;/a&gt;）の2024-02-12は無視され、titleは単にxxxになりますが、Hexoではpost内のtitle front matterから読み取られるため、最終的にpermalinkアドレスを決定するfilterプラグインを作成する必要がありました：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-comment&#34;&gt;/**&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; * permalink 中的 name 不符合预期，对于 _posts/life/2015/xxx.md 来说，在文档中 :name 表示的是 xxx，但是实际是 life-2015-xxx&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; */&lt;/span&gt;&lt;br&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;filter&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;post_permalink&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; (&lt;span class=&#34;hljs-params&#34;&gt;data&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 在这里修改 post.name 的值&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; arr = data.&lt;span class=&#34;hljs-title function_&#34;&gt;split&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;/&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;filter&lt;/span&gt;(&lt;span class=&#34;hljs-title class_&#34;&gt;Boolean&lt;/span&gt;);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; categories = arr[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; name = arr[&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;categories&amp;#125;&lt;/span&gt;/&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;name.split(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;-&amp;#x27;&lt;/span&gt;).filter(&lt;span class=&#34;hljs-built_in&#34;&gt;Boolean&lt;/span&gt;).slice(&lt;span class=&#34;hljs-number&#34;&gt;3&lt;/span&gt;).join(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;-&amp;#x27;&lt;/span&gt;)&amp;#125;&lt;/span&gt;`&lt;/span&gt;;&lt;br&gt;&amp;#125;);&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;また、permalinkは純粋な数字ではなく、文字列でなければなりません：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/jekyll-2-hexo/147800e8-7a61-8006-a660-e8ecfbe7da9a.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;そうしないとエラーが発生します（.endsWithを見ればなぜエラーになるかわかります）：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/jekyll-2-hexo/147800e8-7a61-8032-8e51-d6528f277306.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ejsテンプレート構文問題&#34;&gt;EJSテンプレート構文問題&lt;/h3&gt;
&lt;p&gt;ejsテンプレートをネストする際、Jekyllのliquid構文とは異なり、テンプレート内でfront-matterをカスタマイズできません。つまり、テンプレート間のパラメータ伝達は外側から内側のみで、内側から外側にはできません。例えば、indexのlayoutがpageで、front-matterも設定していますが、このfront-matterはpage.ejsテンプレートから読み取ることができないため、使用するすべての場所でパラメータを下に渡す必要がありました。&lt;/p&gt;
&lt;h3 id=&#34;markdown構文レンダリング問題&#34;&gt;Markdown構文レンダリング問題&lt;/h3&gt;
&lt;p&gt;Hexoに組み込まれているmarkedのmarkdownレンダリングは、jekyllのkarmarkdownレンダリングと異なります。前者は、## h2（改行+空行）段落内の空行+段落を無視しますが、後者は無視しません。&lt;/p&gt;
&lt;p&gt;大した問題ではありませんが、これによりホームページでコンテンツの要約にスペースが1つ足りず完全に一致しないことがあり、私は可能な限り完全に一致させたいと考えました。そうすることでSEOの評価が下がらず、検索エンジンがコンテンツに大きな変更があったと認識しないようにするためです。&lt;/p&gt;
&lt;p&gt;そこで、markdown-itを使用して処理することにし、hexo-renderer-markdown-itをインストールしました。&lt;/p&gt;
&lt;h3 id=&#34;liquidソート問題&#34;&gt;Liquidソート問題&lt;/h3&gt;
&lt;p&gt;Jekyllのliquidのソートは以下のように使用していました：&lt;code&gt;&amp;#123;&amp;#123; tags | split:&#39;`**`SEPARATOR`**`&#39; | sort &amp;#125;&amp;#125;&lt;/code&gt;：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/jekyll-2-hexo/0389dcbb-8bb7-413c-a968-4a77a8b76b71.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;問題は、Liquidのソートでsort部分が同じ場合、後続のhref文字列でソートされるため、これを引き継ぐことになりました：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/jekyll-2-hexo/a24e2d73-ab8b-4b5d-a57d-7e0f2f5f0a66.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;mermaid構文問題&#34;&gt;Mermaid構文問題&lt;/h3&gt;
&lt;p&gt;mermaidはhighlightでハイライトできず、hexoのconfigで除外する必要があります：&lt;/p&gt;
&lt;figure class=&#34;highlight yaml&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs yaml&#34;&gt;&lt;span class=&#34;hljs-attr&#34;&gt;exclude_languages:&lt;/span&gt;&lt;br&gt; &lt;span class=&#34;hljs-bullet&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;mermaid&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;markdownでejs構文が使用できない問題&#34;&gt;MarkdownでEJS構文が使用できない問題&lt;/h3&gt;
&lt;p&gt;一時的に無視し、迂回策を取りました。&lt;/p&gt;
&lt;h3 id=&#34;ページネーション生成問題&#34;&gt;ページネーション生成問題&lt;/h3&gt;
&lt;p&gt;hexo-generator-index の pagination は page/2 page/3 を生成しますが、jekyll では page2, page3 という形式です。そのため、このプラグインのソースコードをコピーしてローカルで修正しました（&lt;code&gt;scripts/pagination.js&lt;/code&gt;に配置）：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-meta&#34;&gt;&amp;#x27;use strict&amp;#x27;&lt;/span&gt;;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; pagination = &lt;span class=&#34;hljs-built_in&#34;&gt;require&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;hexo-pagination&amp;#x27;&lt;/span&gt;);&lt;br&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;config&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;index_generator&lt;/span&gt; = &lt;span class=&#34;hljs-title class_&#34;&gt;Object&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;assign&lt;/span&gt;(&lt;br&gt;  &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;per_page&lt;/span&gt;:&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;typeof&lt;/span&gt; hexo.&lt;span class=&#34;hljs-property&#34;&gt;config&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;per_page&lt;/span&gt; === &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;undefined&amp;#x27;&lt;/span&gt; ? &lt;span class=&#34;hljs-number&#34;&gt;10&lt;/span&gt; : hexo.&lt;span class=&#34;hljs-property&#34;&gt;config&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;per_page&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;order_by&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;-date&amp;#x27;&lt;/span&gt;,&lt;br&gt;  &amp;#125;,&lt;br&gt;  hexo.&lt;span class=&#34;hljs-property&#34;&gt;config&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;index_generator&lt;/span&gt;&lt;br&gt;);&lt;br&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;generator&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;index&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; (&lt;span class=&#34;hljs-params&#34;&gt;locals&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; config = &lt;span class=&#34;hljs-variable language_&#34;&gt;this&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;config&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; posts = locals.&lt;span class=&#34;hljs-property&#34;&gt;posts&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;sort&lt;/span&gt;(config.&lt;span class=&#34;hljs-property&#34;&gt;index_generator&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;order_by&lt;/span&gt;);&lt;br&gt;  posts.&lt;span class=&#34;hljs-property&#34;&gt;data&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;sort&lt;/span&gt;(&lt;span class=&#34;hljs-function&#34;&gt;(&lt;span class=&#34;hljs-params&#34;&gt;a, b&lt;/span&gt;) =&amp;gt;&lt;/span&gt; (b.&lt;span class=&#34;hljs-property&#34;&gt;sticky&lt;/span&gt; || &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;) - (a.&lt;span class=&#34;hljs-property&#34;&gt;sticky&lt;/span&gt; || &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;));&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; paginationDir = config.&lt;span class=&#34;hljs-property&#34;&gt;pagination_dir&lt;/span&gt; || &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;page&amp;#x27;&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; path = config.&lt;span class=&#34;hljs-property&#34;&gt;index_generator&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;path&lt;/span&gt; || &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;pagination&lt;/span&gt;(path, posts, &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;perPage&lt;/span&gt;: config.&lt;span class=&#34;hljs-property&#34;&gt;index_generator&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;per_page&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;layout&lt;/span&gt;: [&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;index&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;archive&amp;#x27;&lt;/span&gt;],&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;format&lt;/span&gt;: paginationDir + &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;%d/&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;data&lt;/span&gt;: &amp;#123;&lt;br&gt;      &lt;span class=&#34;hljs-attr&#34;&gt;__index&lt;/span&gt;: &lt;span class=&#34;hljs-literal&#34;&gt;true&lt;/span&gt;,&lt;br&gt;    &amp;#125;,&lt;br&gt;  &amp;#125;);&lt;br&gt;&amp;#125;);&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;打ち消し線の実装問題&#34;&gt;打ち消し線の実装問題&lt;/h3&gt;
&lt;p&gt;デフォルトの打ち消し線は s タグですが、jekyll では del タグを使用します。after_render:html で直接置換しました（&lt;code&gt;scripts/tag-del.js&lt;/code&gt;に配置）：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;filter&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;after_render:html&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; (&lt;span class=&#34;hljs-params&#34;&gt;str&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; str.&lt;span class=&#34;hljs-title function_&#34;&gt;replace&lt;/span&gt;(&lt;span class=&#34;hljs-regexp&#34;&gt;/&amp;lt;s&amp;gt;/g&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;lt;del&amp;gt;&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;replace&lt;/span&gt;(&lt;span class=&#34;hljs-regexp&#34;&gt;/&amp;lt;\/s&amp;gt;/g&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;lt;/del&amp;gt;&amp;#x27;&lt;/span&gt;);&lt;br&gt;&amp;#125;);&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;hr /&gt;
&lt;h3 id=&#34;ビルド後の余分なファイル問題&#34;&gt;ビルド後の余分なファイル問題&lt;/h3&gt;
&lt;p&gt;いくつかのファイルは不要なため、ビルド後に削除します：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2025/jekyll-2-hexo/147800e8-7a61-8077-911f-f5d55f484628.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;具体的には：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;categories/*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;i_dont_wanna_use_default_archives/*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;i_dont_wanna_use_default_tags/*&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;less/*&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;rss-問題&#34;&gt;RSS 問題&lt;/h3&gt;
&lt;p&gt;Notion Bookmark からのレンダリングにカスタムタグスタイルを使用し、Notion の Bookmark と同じように見栄えを良くしようとしましたが、これにより Reeder などの RSS リーダーでスタイルが正しくレンダリングされなくなりました。そのため、Jekyll ではテンプレート構文の処理関数を使用してビルド時にカスタムスタイルを動的に置換するようにしました：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-variable language_&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-variable language_&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;BookmarkFilter&lt;/span&gt;&lt;br&gt;      def &lt;span class=&#34;hljs-title function_&#34;&gt;bookmark_filter&lt;/span&gt;(input)&lt;br&gt;        input.&lt;span class=&#34;hljs-title function_&#34;&gt;gsub&lt;/span&gt;(&lt;span class=&#34;hljs-regexp&#34;&gt;/^\&amp;lt;p\&amp;gt;\&amp;lt;a\s+class=\&amp;quot;link-bookmark\&amp;quot;\shref=(.*)\starget=\&amp;quot;_blank\&amp;quot;\&amp;gt;\&amp;lt;span\&amp;gt;(.*)\&amp;lt;\/span\&amp;gt;\&amp;lt;span\&amp;gt;\&amp;lt;span\&amp;gt;(.*)\&amp;lt;\/span\&amp;gt;\&amp;lt;span\&amp;gt;\n(.*)\n\&amp;lt;\/span\&amp;gt;\&amp;lt;span\&amp;gt;(.*)\&amp;lt;\/span\&amp;gt;\&amp;lt;\/span\&amp;gt;\&amp;lt;\/a\&amp;gt;\&amp;lt;\/p\&amp;gt;$/&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;lt;p&amp;gt;&amp;lt;a href=\1 target=&amp;quot;_blank&amp;quot;&amp;gt;\3&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;#x27;&lt;/span&gt;);&lt;br&gt;      end&lt;br&gt;    end&lt;br&gt;  end&lt;br&gt;  &lt;br&gt;  &lt;span class=&#34;hljs-title class_&#34;&gt;Liquid&lt;/span&gt;::&lt;span class=&#34;hljs-title class_&#34;&gt;Template&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register_filter&lt;/span&gt;(&lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;::&lt;span class=&#34;hljs-title class_&#34;&gt;BookmarkFilter&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Hexo ではビルド後にパッチを当てる方式で処理しています（&lt;code&gt;scripts/rss-gene.js&lt;/code&gt;に配置）：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;50&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;51&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;52&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;53&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;54&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;55&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;56&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;57&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;58&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;59&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;60&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;61&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;62&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;63&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;64&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;65&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;66&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;67&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;68&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;69&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;70&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;71&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;72&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;73&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;74&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;75&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;76&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;77&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;78&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;79&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;80&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;81&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;82&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;83&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;84&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;85&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;86&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;87&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;88&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;89&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;90&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;91&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;92&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;93&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;94&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;95&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;96&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;97&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; fs = &lt;span class=&#34;hljs-built_in&#34;&gt;require&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;fs&amp;#x27;&lt;/span&gt;);&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; path = &lt;span class=&#34;hljs-built_in&#34;&gt;require&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;path&amp;#x27;&lt;/span&gt;);&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; ejs = &lt;span class=&#34;hljs-built_in&#34;&gt;require&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;ejs&amp;#x27;&lt;/span&gt;);&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; rootDate = &lt;span class=&#34;hljs-keyword&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Date&lt;/span&gt;();&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;getDate&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;_date&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; date = _date ? &lt;span class=&#34;hljs-keyword&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Date&lt;/span&gt;(_date) : rootDate;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 获取各个部分&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; days = [&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Sun&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Mon&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Tue&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Wed&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Thu&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Fri&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Sat&amp;#x27;&lt;/span&gt;];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; months = [&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Jan&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Feb&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Mar&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Apr&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;May&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Jun&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Jul&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Aug&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Sep&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Oct&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Nov&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Dec&amp;#x27;&lt;/span&gt;,&lt;br&gt;  ];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; dayName = days[date.&lt;span class=&#34;hljs-title function_&#34;&gt;getDay&lt;/span&gt;()];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; day = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(date.&lt;span class=&#34;hljs-title function_&#34;&gt;getDate&lt;/span&gt;()).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; month = months[date.&lt;span class=&#34;hljs-title function_&#34;&gt;getMonth&lt;/span&gt;()];&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; year = date.&lt;span class=&#34;hljs-title function_&#34;&gt;getFullYear&lt;/span&gt;();&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; hours = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(date.&lt;span class=&#34;hljs-title function_&#34;&gt;getHours&lt;/span&gt;()).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; minutes = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(date.&lt;span class=&#34;hljs-title function_&#34;&gt;getMinutes&lt;/span&gt;()).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; seconds = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(date.&lt;span class=&#34;hljs-title function_&#34;&gt;getSeconds&lt;/span&gt;()).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 获取时区偏移（以分钟为单位）&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; timezoneOffset = -date.&lt;span class=&#34;hljs-title function_&#34;&gt;getTimezoneOffset&lt;/span&gt;();&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; sign = timezoneOffset &amp;gt;= &lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt; ? &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;+&amp;#x27;&lt;/span&gt; : &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;-&amp;#x27;&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; offsetHours = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(&lt;br&gt;    &lt;span class=&#34;hljs-title class_&#34;&gt;Math&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;floor&lt;/span&gt;(&lt;span class=&#34;hljs-title class_&#34;&gt;Math&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;abs&lt;/span&gt;(timezoneOffset) / &lt;span class=&#34;hljs-number&#34;&gt;60&lt;/span&gt;)&lt;br&gt;  ).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; offsetMinutes = &lt;span class=&#34;hljs-title class_&#34;&gt;String&lt;/span&gt;(&lt;span class=&#34;hljs-title class_&#34;&gt;Math&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;abs&lt;/span&gt;(timezoneOffset) % &lt;span class=&#34;hljs-number&#34;&gt;60&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;padStart&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;0&amp;#x27;&lt;/span&gt;);&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 格式化为 RFC 2822 格式的字符串&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;dayName&amp;#125;&lt;/span&gt;, &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;day&amp;#125;&lt;/span&gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;month&amp;#125;&lt;/span&gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;year&amp;#125;&lt;/span&gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;hours&amp;#125;&lt;/span&gt;:&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;minutes&amp;#125;&lt;/span&gt;:&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;seconds&amp;#125;&lt;/span&gt; &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;sign&amp;#125;&lt;/span&gt;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;offsetHours&amp;#125;&lt;/span&gt;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;offsetMinutes&amp;#125;&lt;/span&gt;`&lt;/span&gt;;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;br&gt;hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;generator&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;register&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;xml&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; (&lt;span class=&#34;hljs-params&#34;&gt;locals&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 仿照 Liquid 内置的日期格式写法&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 注意如果前面不加这个 \uFEFF 则不会被识别为 xml&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; template =&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;\uFEFF&amp;#x27;&lt;/span&gt; +&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;`&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;lt;rss version=&amp;quot;2.0&amp;quot; xmlns:atom=&amp;quot;http://www.w3.org/2005/Atom&amp;quot;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;lt;channel&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;title&amp;gt;Xheldon Blog&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;description&amp;gt;The Answer to Life, the Universe and Everything is...&amp;lt;/description&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;link&amp;gt;https://www.xheldon.com&amp;lt;/link&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;atom:link href=&amp;quot;https://www.xheldon.com/feed.xml&amp;quot; rel=&amp;quot;self&amp;quot; type=&amp;quot;application/rss+xml&amp;quot; /&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;pubDate&amp;gt;&amp;lt;%= getDate() %&amp;gt;&amp;lt;/pubDate&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;lastBuildDate&amp;gt;&amp;lt;%= getDate() %&amp;gt;&amp;lt;/lastBuildDate&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;generator&amp;gt;Hexo v&amp;lt;%= version %&amp;gt;&amp;lt;/generator&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;% for (post of posts.sort((a, b) =&amp;gt; (new Date(b.date).getTime()) - (new Date(a.date).getTime())).slice(0, 10)) &amp;#123; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;item&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;title&amp;gt;&amp;lt;%= post.title %&amp;gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;description&amp;gt;&amp;lt;%= bookmark_filter(post.content) %&amp;gt;&amp;lt;/description&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;pubDate&amp;gt;&amp;lt;%= getDate(post.date) %&amp;gt;&amp;lt;/pubDate&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;link&amp;gt;&amp;lt;%= post.permalink %&amp;gt;&amp;lt;/link&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;guid isPermaLink=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;%= post.permalink %&amp;gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;% for (tag of post.tags.data) &amp;#123; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;                &amp;lt;category&amp;gt;&amp;lt;%= tag.name %&amp;gt;&amp;lt;/category&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;% &amp;#125; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;% for (cat of post.categories.data) &amp;#123; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;                &amp;lt;category&amp;gt;&amp;lt;%- escape_html(cat.name) %&amp;gt;&amp;lt;/category&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;            &amp;lt;% &amp;#125; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;/item&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;        &amp;lt;% &amp;#125; %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;lt;/channel&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;lt;/rss&amp;gt;`&lt;/span&gt;;&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; bookmark_filter = hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;helper&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;get&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;bookmark_filter&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;bind&lt;/span&gt;(hexo);&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; escape_html = hexo.&lt;span class=&#34;hljs-property&#34;&gt;extend&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;helper&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;get&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;escape_html&amp;#x27;&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;bind&lt;/span&gt;(hexo);&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; data = &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;posts&lt;/span&gt;: locals.&lt;span class=&#34;hljs-property&#34;&gt;posts&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;toArray&lt;/span&gt;(),&lt;br&gt;    getDate,&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;version&lt;/span&gt;: hexo.&lt;span class=&#34;hljs-property&#34;&gt;version&lt;/span&gt;,&lt;br&gt;    escape_html,&lt;br&gt;    bookmark_filter,&lt;br&gt;  &amp;#125;;&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; jsonContent = ejs.&lt;span class=&#34;hljs-title function_&#34;&gt;render&lt;/span&gt;(template, data);&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; outputPath = path.&lt;span class=&#34;hljs-title function_&#34;&gt;join&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;source/_posts&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;feed.xml&amp;#x27;&lt;/span&gt;);&lt;br&gt;  fs.&lt;span class=&#34;hljs-title function_&#34;&gt;writeFileSync&lt;/span&gt;(outputPath, jsonContent, &amp;#123; &lt;span class=&#34;hljs-attr&#34;&gt;encoding&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;utf8&amp;#x27;&lt;/span&gt; &amp;#125;);&lt;br&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;path&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;feed.xml&amp;#x27;&lt;/span&gt;,&lt;br&gt;    &lt;span class=&#34;hljs-attr&#34;&gt;data&lt;/span&gt;: jsonContent,&lt;br&gt;  &amp;#125;;&lt;br&gt;&amp;#125;);&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&#34;service-worker-問題&#34;&gt;Service-Worker 問題&lt;/h3&gt;
&lt;p&gt;service worker を削除しました。ビルドごとにページの tags 部分が必ず変更され、html ページが更新されるため、頻繁に手動でページをリフレッシュする必要があり煩わしかったからです。&lt;/p&gt;
&lt;h3 id=&#34;その他の問題&#34;&gt;その他の問題&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;必要なファイルが含まれていない場合があり、ビルド後に追加します（ads.txt など）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;layout&lt;/code&gt;の値が&lt;code&gt;post&lt;/code&gt;タイプの記事で、&lt;code&gt;page.path&lt;/code&gt;の値が&lt;code&gt;/&lt;/code&gt;で始まらない場合があるので注意が必要です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;あとがき&#34;&gt;あとがき&lt;/h2&gt;
&lt;p&gt;基本的には以上です。BeyondCompare で行ごとに比較することで、変更を最小限に抑えつつ移行できました。&lt;/p&gt;
</description>
            <pubDate>Tue, 07 Jan 2025 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/jekyll-2-hexo.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/jekyll-2-hexo.html</guid>
            
                <category>使用体验</category>
            
                <category>折腾</category>
            
                <category>总结</category>
            
                <category>教程</category>
            
                <category>技巧</category>
            
                <category>JavaScript</category>
            
                <category>技术</category>
            
                <category>框架</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>サイバーパンク2024：私が現在使用しているツールたち</title>
            <description>&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;2024年も終わりに近づき、WeChatのコンテンツブーストクーポンの有効期限が迫っているのを機に、今年私が日常の開発で頻繁に使用している様々な効率化ツールをまとめてみました。ソフトウェアとハードウェア両方を含み、参考までにご紹介します。&lt;/p&gt;
&lt;p caption=&#39;AI 生成图&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80d5-99b3-da02d3eacde4.webp&#39; alt=&#39;AI 生成图&#39; title=&#39;AI 生成图&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;有料サブスクリプションソフトウェア&#34;&gt;有料サブスクリプションソフトウェア&lt;/h2&gt;
&lt;h3 id=&#34;crusor&#34;&gt;Crusor&lt;/h3&gt;
&lt;p&gt;AIプログラミングにおいて真っ先に挙げるべきはCursorです。&lt;/p&gt;
&lt;p&gt;WindsurfやGithub Copilotとの比較では、新規コード生成能力はほぼ互角ですが、Cursorの既存コードの修正/リファクタリング能力は他のAIコード支援ツールを一歩凌駕しています。基本的にはTabキーを押すだけで、自動的にカーソル（Cursor）がリファクタリング/修正が必要な箇所に移動し、Tabで変更を受け入れ、次の修正ポイントにジャンプします。そのComposer/Agent機能もAIペアプログラミングの先駆者として、その実力は疑いようがありません。&lt;/p&gt;
&lt;p caption=&#39;使用 Cursor 的日常编程界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8053-865f-cbdc451a31ad.webp&#39; alt=&#39;使用 Cursor 的日常编程界面&#39; title=&#39;使用 Cursor 的日常编程界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;notion&#34;&gt;Notion&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 私が使用する機能は無料版で十分であり、有料版は主にコラボレーション用途です。そのため来年はサブスクリプションを更新しない予定です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;私がノートアプリに求める最も重要な2点は「制限のないインポート/エクスポート」と「全プラットフォーム対応」です。Notionはこれを実現しており：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;API機能をサポートしているため、サービス終了時のデータエクスポート問題がありません（独自フォーマットのEvernoteなど国内ノートアプリとは対照的です）；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;APIを利用し、Notion-Flowブラウザ拡張と組み合わせることで、Githubベースの静的ブログをどこからでも執筆可能；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;databaseモジュール機能を使えば、少しサーバーサイドコードを書くだけでネットワークデータベースとして活用可能（私のブログページで実践している通り）：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&#34;https://www.xheldon.cn/subscribe/&#34; target=&#34;_blank&#34;&gt; 订阅&amp;付费软件 - Xheldon Blog&lt;/a&gt;&lt;/p&gt;
&lt;p caption=&#39;Notion Flow 插件界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80ed-b18b-fd360fdc9098.webp&#39; alt=&#39;Notion Flow 插件界面&#39; title=&#39;Notion Flow 插件界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;滴答清单（ticktick）&#34;&gt;滴答清单（TickTick）&lt;/h3&gt;
&lt;p&gt;以前はThingsを買い切りで使用していましたが、カレンダー連携に違和感があり、友人に勧められて滴答清单に移行しました。&lt;/p&gt;
&lt;p&gt;カレンダー、タスク、リストビューが非常に便利で、タスク詳細はリッチテキスト対応しています。これが買い切りではなくサブスクリプション制を採用している理由でしょう。継続的なサーバーストレージコストが必要だからです。&lt;/p&gt;
&lt;p caption=&#39;滴答清单&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-807e-aa46-e617dece267c.webp&#39; alt=&#39;滴答清单&#39; title=&#39;滴答清单&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;1password&#34;&gt;1Password&lt;/h3&gt;
&lt;p&gt;パスワード管理ソフトの王者と呼ぶにふさわしいツールです。様々なシーンで手入力から解放され、APIトークン、クレジットカード情報、SSH情報、リカバリーコードのプレーンテキスト、WiFiアカウント情報など多様な形式の保存が可能です。&lt;/p&gt;
&lt;p&gt;システムとの深い統合により、「パスワードを入力しない」を極限まで追求しています。iOSではシステムキーボード使用時のみ呼び出せるため、これが私がスマホでサードパーティ製IMEを使わない主な理由です。&lt;/p&gt;
&lt;p&gt;セキュリティ面では、商用ソフトウェアをより信頼しています。&lt;/p&gt;
&lt;p caption=&#39;1Password&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80d7-aea0-cecb9be5a8ab.webp&#39; alt=&#39;1Password&#39; title=&#39;1Password&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;youtube-premium&#34;&gt;Youtube Premium&lt;/h3&gt;
&lt;p&gt;これを効率化ツールとしてカウントする理由は、主に新しいことを学ぶために使用しているからです。わからないことがあれば検索すれば、必ず関連コンテンツが見つかります。最近ではAI関連、少し前ならSwift関連など、はたまた性愛テクニックを解説するブロガーまで（もちろん個人メディアなので真偽は自己判断）。ただし低品質コンテンツもあるので、ネットサーフィンには注意が必要です。&lt;/p&gt;
&lt;p&gt;Premium会員の「特典」として、YouTube Musicも無料で利用可能です。Apple Musicのプレイリストをインポート（サードパーティサービス経由）したり、自分で音楽ファイルをアップロードしたりできます。Apple Musicとの比較優位点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;YouTube Musicはアップロードした楽曲をオンライン楽曲で勝手に置き換えません；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最大10万曲までアップロード可能；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;YouTube Premiumを解約後も、アップロードした音楽は引き続き利用可能で、音楽用クラウドストレージとして機能します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p caption=&#39;我的 YouTube Music&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/161800e8-7a61-8089-b694-c40de53f4c15.webp&#39; alt=&#39;我的 YouTube Music&#39; title=&#39;我的 YouTube Music&#39;&gt;&lt;/p&gt;
&lt;p&gt;消費ダウングレードの原則に従い、2024年末にApple Musicの契約が切れるタイミングで解約し、YouTube Premiumに乗り換えました。&lt;/p&gt;
&lt;p caption=&#39;我的 YouTube 主页&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15f800e8-7a61-801c-bdb9-dade7616324d.webp&#39; alt=&#39;我的 YouTube 主页&#39; title=&#39;我的 YouTube 主页&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;買い切りソフトウェア&#34;&gt;買い切りソフトウェア&lt;/h2&gt;
&lt;h3 id=&#34;popclip&#34;&gt;Popclip&lt;/h3&gt;
&lt;p&gt;右手だけで即座に検索＆翻訳＆各種操作が可能で、左手やキーボード不要です。&lt;/p&gt;
&lt;p&gt;私の使用例：テキスト選択後OpenAI Translatorを起動し、そこでタスクを設定（後述）。&lt;/p&gt;
&lt;p caption=&#39;PopClip 主页&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-809a-b407-fedb0270ab0b.webp&#39; alt=&#39;PopClip 主页&#39; title=&#39;PopClip 主页&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;alfred-5&#34;&gt;Alfred 5&lt;/h3&gt;
&lt;p&gt;バージョン4の買い切り版からアップグレードしました。主にアプリランチャーとして、およびOpenAITranslateと連携したAI質問用に使用。カスタムスクリプトを作成し、上記と同じ方法で呼び出します。&lt;/p&gt;
&lt;p caption=&#39;Alfred 主界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8013-ba20-fde096aa3bf9.webp&#39; alt=&#39;Alfred 主界面&#39; title=&#39;Alfred 主界面&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;Alfred 自定义脚本界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/161800e8-7a61-800e-a495-cd4e85400abd.webp&#39; alt=&#39;Alfred 自定义脚本界面&#39; title=&#39;Alfred 自定义脚本界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;bettermouse&#34;&gt;Bettermouse&lt;/h3&gt;
&lt;p&gt;私はロジックのゲーミングマウスを使用しており、ロジックにはG HUBソフトウェアがありますが、このソフトウェアには多くの問題があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;タスクバーでは、黒いアイコンだけが目立ち、他の白いアイコンの中では異質に見える。&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;特立独行的 G Hub 软件&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80ea-8bc1-f301acb45cdd.webp&#39; alt=&#39;特立独行的 G Hub 软件&#39; title=&#39;特立独行的 G Hub 软件&#39;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;インタラクションロジックが奇妙。ソフトウェアを開きたい場合、タスクバーをクリックし、その後「G HUBを起動」をクリックする必要がある。一般的なソフトウェアのインタラクションは、クリックでメインウィンドウが開き、右クリックでインタラクションメニューが表示される。最低でも、ユーザーがインタラクションを決定できるオプションを提供してほしい。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;操作が重い。起動に30秒かかり、時々起動できず、アニメーション画面でフリーズする。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;テキスト説明が分かりにくい。マウスをオンボードにしたい場合、このオプションでは「有効にする」をクリックすべきか、現状のままで良いのか教えてほしい。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;离谱的文案描述&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-807e-bc82-e1b1057cf7b7.webp&#39; alt=&#39;离谱的文案描述&#39; title=&#39;离谱的文案描述&#39;&gt;&lt;/p&gt;
&lt;p&gt;Bettermouseは、マウスの移動速度をカスタマイズできるだけでなく、スムーズスクロールや右クリックドラッグなどの高度なインタラクションも設定可能（例えばFigmaでページをスクロールするにはcmdを押しながら左クリックで移動する必要があるが、Bettermouseでは右クリックでページをドラッグできるなど）。&lt;/p&gt;
&lt;p caption=&#39;BetterMouse 软件设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80d2-b103-c9c785b85f43.webp&#39; alt=&#39;BetterMouse 软件设置&#39; title=&#39;BetterMouse 软件设置&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;magnet&#34;&gt;Magnet&lt;/h3&gt;
&lt;p&gt;何年も前に購入したウィンドウ管理ツールで、Apple IDと共に一台また一台のMacにインストールされてきた。ショートカットキーでウィンドウの画面占有率を調整できるのが「非～常～に～便利」。市場には同様の機能を持つソフトウェアが多数あるが、私にとってはこれで十分で、複数のバージョンアップを経て機能もさらに豊富になり、まったく置き換える気が起きない。&lt;/p&gt;
&lt;p caption=&#39;Magnet 软件设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8051-81d6-d51835aaeb7b.webp&#39; alt=&#39;Magnet 软件设置&#39; title=&#39;Magnet 软件设置&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;cleanshotx&#34;&gt;CleanshotX&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; メジャーバージョン買い切り&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;最強のスクリーンショット/録画ツールで、途中で有料アップグレードもした。最も気に入っている機能は：スクリーンショット後ワンクリックでクリップボードにコピー、スクリーンショット後ワンクリックで画面に固定（最もよく使う）。使用シーンは、何かを見ても覚えられない（年を取るにつれて脳のコンテキスト容量が低下しているため）場合に、何度も切り替える必要がなく、スクリーンショットを固定することでこの煩わしさを解消できる。&lt;/p&gt;
&lt;p caption=&#39;置顶截图&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-808f-90e9-c31105514fac.webp&#39; alt=&#39;置顶截图&#39; title=&#39;置顶截图&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;surge-quantumultx&#34;&gt;Surge/QuantumultX&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; メジャーバージョン買い切り&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Clashカーネルが更新されなくなったためClashX「小猫咪」を放棄し、友人とMac Surgeの5人乗りをシェアした。スマホではQuantumultXを使用。&lt;/p&gt;
&lt;p caption=&#39;使用 Surge 当网关&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80f7-8620-c8391a537a25.webp&#39; alt=&#39;使用 Surge 当网关&#39; title=&#39;使用 Surge 当网关&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;xpic（私貨混入）&#34;&gt;xPic（私貨混入）&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; これは私的な推薦、私が開発したものです、笑&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;仕事で画像の圧縮や変換が必要だが、オンラインツールでは期待通りにならないか、アップロード/ダウンロードが面倒か、プライバシー問題がある。そこでxPicというツールを開発した。画像と動画の圧縮、フォーマット変換、画像シーケンスフレームの合成、動画からGifへの変換をサポート。&lt;/p&gt;
&lt;p&gt;また、仕事でSVGAを使用しているため、SVGAの簡単なプレビューもサポートしている。まだバグがあり、ベータテスト中。&lt;/p&gt;
&lt;p caption=&#39;xPic SVGA 预览&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8072-a02d-f69887f17f73.webp&#39; alt=&#39;xPic SVGA 预览&#39; title=&#39;xPic SVGA 预览&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;無料-オープンソースソフトウェア&#34;&gt;無料/オープンソースソフトウェア&lt;/h2&gt;
&lt;h3 id=&#34;openai-translator&#34;&gt;OpenAI Translator&lt;/h3&gt;
&lt;p&gt;翻訳ツール自体は特に推薦するものではないが、PopClipから呼び出せるのが特徴（原理はソフトウェアに登録されたUnixソケットにデータを送信し、コマンド：&lt;code&gt;curl -d &amp;quot;$1&amp;quot; --unix-socket /tmp/openai-translator.sock http://openai-translator&lt;/code&gt;で呼び出せる）。これによりPopClipやAlfredと連携してAIに素早く質問できる。&lt;/p&gt;
&lt;p caption=&#39;OpenAI Translator 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8071-9f06-d2abc7033bb2.webp&#39; alt=&#39;OpenAI Translator 界面&#39; title=&#39;OpenAI Translator 界面&#39;&gt;&lt;/p&gt;
&lt;p&gt;新しいタスクを追加した：&lt;/p&gt;
&lt;p caption=&#39;OpenAI Translator 设置界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80fe-8c06-fdfbe61d1174.webp&#39; alt=&#39;OpenAI Translator 设置界面&#39; title=&#39;OpenAI Translator 设置界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;微信入力法&#34;&gt;微信入力法&lt;/h3&gt;
&lt;p&gt;iPhoneでは微信入力法を使用せず、会社や自宅のMacでのみ使用している。共有辞書が優れている。以前は搜狗入力法を使用していたが、搜狗がTencentに買収された後、意図的に劣化させられユーザーを移行させようとしているのか、全く入力したことのない単語が頻繁に表示される。例えば&lt;code&gt;zhuomian&lt;/code&gt;と入力すると、最初の候補が「卓面」で「桌面」ではない。&lt;/p&gt;
&lt;p&gt;もう一つの問題は、キーボードで戦っている時に「屄」という字を入力したことがあるが、搜狗入力法が私の癖を発見したかのように、biの同音字を意図的に何度も入力して「頻度調整」でこの候補を後ろに移動させようとしても失敗する。一時的に2ページ目に移動させても、しばらくするとまた最初の候補に戻ってしまう（この期間にこの字を入力していないことを誓う）。&lt;/p&gt;
&lt;p&gt;関連するもう一つの問題は、いつでも（調整直後でも）&lt;code&gt;vi&lt;/code&gt;と入力すると、入力法が&lt;code&gt;bi&lt;/code&gt;と入力したいと判断する（キーボードで&lt;code&gt;v&lt;/code&gt;と&lt;code&gt;b&lt;/code&gt;が隣接しているため、この判断は自然）。この時、意図的に調整した&lt;code&gt;bi&lt;/code&gt;の候補順序を無視し、「屄」を優先表示するため、画面共有時に非常に恥ずかしい思いをする。&lt;/p&gt;
&lt;p&gt;iPhoneで使用しない理由は、1Passwordの自動入力/認証コード自動入力がネイティブキーボードのみで可能なため。&lt;/p&gt;
&lt;p caption=&#39;微信输入法设置界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80e8-9e42-c558615951bf.webp&#39; alt=&#39;微信输入法设置界面&#39; title=&#39;微信输入法设置界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;orbstack&#34;&gt;OrbStack&lt;/h3&gt;
&lt;p&gt;ネイティブのDocker/Linux/k8s管理ツールで、インターフェースが洗練されており、操作が簡単で、メモリ使用量が少ない。無料版でも十分で、Docker Desktopとは比べ物にならない。公式の比較はこちら：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.orbstack.dev/compare/docker-desktop&#34; target=&#34;_blank&#34;&gt; OrbStack vs. Docker Desktop · OrbStack Docs&lt;/a&gt;&lt;/p&gt;
&lt;p caption=&#39;OrbStack 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8025-bacc-d810a6a81df6.webp&#39; alt=&#39;OrbStack 界面&#39; title=&#39;OrbStack 界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;immersive-translate&#34;&gt;Immersive translate&lt;/h3&gt;
&lt;p&gt;AI翻訳プラグイン。ウェブ閲覧時にホットキーで全文翻訳可能なほか、マウスホバー箇所のみの翻訳も対応。独自APIの提供をサポート。YouTube字幕の翻訳も可能で、Googleの機械翻訳とは比べ物にならない精度。&lt;/p&gt;
&lt;p&gt;（追記：Googleが大規模言語モデルを開発しているのに、なぜ自社ドキュメントをAI翻訳せず、未だに読みづらい機械翻訳を使い続けるのか？）&lt;/p&gt;
&lt;p caption=&#39;Immersive translate 官网&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8087-8c69-f9aa44bfb9be.webp&#39; alt=&#39;Immersive translate 官网&#39; title=&#39;Immersive translate 官网&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;warp&#34;&gt;Warp&lt;/h3&gt;
&lt;p&gt;キラー機能：テキスト編集のようにbashコマンドを入力できる。&lt;/p&gt;
&lt;p&gt;iTerm2やターミナルで直接コマンド入力する場合、&lt;code&gt;vim&lt;/code&gt;ショートカットなどが使えないなど制約が多い。この機能がなければWarpを使わないだろう。AIやコラボレーションなど、私には不要な機能が多すぎる。&lt;/p&gt;
&lt;p caption=&#39;Wrap 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8003-bec7-c767006042fb.webp&#39; alt=&#39;Wrap 界面&#39; title=&#39;Wrap 界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;syntax-highlight&#34;&gt;Syntax Highlight&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; オープンソース&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;スペースキー押下でファイルプレビュー可能。豊富なフォーマット対応で、と～っても便利～&lt;/p&gt;
&lt;p caption=&#39;Syntax Highlight 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8096-af2a-e71c652a4594.webp&#39; alt=&#39;Syntax Highlight 界面&#39; title=&#39;Syntax Highlight 界面&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;monitorcontrol&#34;&gt;MonitorControl&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; オープンソース&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;その名の通り、ディスプレイ輝度調整ソフト。ホットキー対応で非常に便利。&lt;/p&gt;
&lt;p caption=&#39;MonitorControl 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8089-9377-d223950afe0c.webp&#39; alt=&#39;MonitorControl 界面&#39; title=&#39;MonitorControl 界面&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;クラックソフト&#34;&gt;クラックソフト&lt;/h2&gt;
&lt;h3 id=&#34;tableplus&#34;&gt;TablePlus&lt;/h3&gt;
&lt;p&gt;サーバーDB接続用に稀に使用（私はプロの運用/サーバーサイドエンジニアではないため）。UIが美しく操作も簡単。&lt;/p&gt;
&lt;p caption=&#39;TablePlus 界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8039-8cd7-c4d3be294f4a.webp&#39; alt=&#39;TablePlus 界面&#39; title=&#39;TablePlus 界面&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;ハードウェア&#34;&gt;ハードウェア&lt;/h2&gt;
&lt;h3 id=&#34;g309マウス&#34;&gt;G309マウス&lt;/h3&gt;
&lt;p&gt;四文字で表現：大満足。&lt;/p&gt;
&lt;p&gt;クリック感が爽快、Bluetooth/無線デュアルモード（Bluetoothはおまけ程度）、無線接続でもピンポイントの反応（ポーリングレート）、やや盛り上がった背面、垂直な側面、付属の滑り止めシート。全てが完璧。&lt;/p&gt;
&lt;p&gt;注：以前使用したG403とG502有線版は非対称マウス（右ボタンが低い位置）だった。対称型のG309では左右ボタンが同位置のため、中指が右クリック時に誤操作しやすく、少し浮かせる必要があったが慣れた。&lt;/p&gt;
&lt;p caption=&#39;小手友好的 G309（虽然我是大手）&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8015-b435-d15e54c1bd29.webp&#39; alt=&#39;小手友好的 G309（虽然我是大手）&#39; title=&#39;小手友好的 G309（虽然我是大手）&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;apple-watchバンド&#34;&gt;Apple Watchバンド&lt;/h3&gt;
&lt;p&gt;某タオバオ店舗で購入。正規品と称し開封後返品不可。正規価格の1/3～1/2で、実際に正規品と違いなし。店舗にはノーブランド包装の正規品/99新/95新品もあり、レビューから工場流出品/瑕疵品/公式返品品と確認。中古売却を考慮し正規包装品を購入したが、99新品のノーブランド品も多数あり。&lt;/p&gt;
&lt;p caption=&#39;各种表带&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-806d-a1b5-eb2218516b61.webp&#39; alt=&#39;各种表带&#39; title=&#39;各种表带&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;airpods-4-ノイズキャンセリング版&#34;&gt;AirPods 4 ノイズキャンセリング版&lt;/h3&gt;
&lt;p&gt;AirPods Pro 2を売却。着け心地が悪く、2年近く使用したため新調。4代ノイズキャンセリング版を購入。Pro 2代比べノイズキャンセリング効果に差はあるが許容範囲。意外にもイヤーピースの上下スライドで音量調節が不可な点以外は満足。&lt;/p&gt;
&lt;p caption=&#39;AirPods 4 降噪版&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-8069-8274-f67ac1401a27.webp&#39; alt=&#39;AirPods 4 降噪版&#39; title=&#39;AirPods 4 降噪版&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;小米-ih炊飯器-s1&#34;&gt;&lt;strong&gt;小米 IH炊飯器 S1&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;8年使用した美的炊飯器（故障はなし）を更新。使用感は良好だが、粥（おかゆ）炊飯に1時間半かかる点に驚愕。&lt;/p&gt;
&lt;p caption=&#39;小米电饭锅&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-804b-9e0a-c48863912c40.webp&#39; alt=&#39;小米电饭锅&#39; title=&#39;小米电饭锅&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;メリダ・エクスプローラーxフラットバーロードバイク&#34;&gt;メリダ・エクスプローラーXフラットバーロードバイク&lt;/h3&gt;
&lt;p&gt;電子機器ではないが、プログラマー生活の一部として記載。通勤用で毎日往復20分。非常に便利～&lt;/p&gt;
&lt;p caption=&#39;探索者 X 在雁栖湖&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/the-tools-i-used-in-2024/15a800e8-7a61-80ba-bf2e-e14e392280c4.webp&#39; alt=&#39;探索者 X 在雁栖湖&#39; title=&#39;探索者 X 在雁栖湖&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;あとがき&#34;&gt;あとがき&lt;/h2&gt;
&lt;p&gt;皆さんの愛用ツールをぜひ教えてください～&lt;/p&gt;
</description>
            <pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/life/the-tools-i-used-in-2024.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/life/the-tools-i-used-in-2024.html</guid>
            
                <category>生活</category>
            
                <category>经验</category>
            
                <category>工具</category>
            
                <category>AI</category>
            
            
                <category>life</category>
            
        </item>
        
        <item>
            <title>TP-LinkでDHCPを無効にした後にダイヤルアップ接続する方法</title>
            <description>&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; ネットワークはすでに設定済みなので、一部のページでは画像の代わりにテキストを使用します。ブログを書くために再度ネットワークをリセットするのは面倒ですから。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;私が購入したTP-Link XDR-5480には奇妙な仕様があります：ルーターのDHCPサービスを無効にすると、すべてのポート（SPF変換ポートを含む）がLanポートに変わってしまい、光モデムのブリッジ接続+ルーターPPPoE接続ができなくなります。さらに、LanポートのIPアドレスは指定できず、すべてフロントエンドルーター（つまり光モデム）から取得されます。&lt;/p&gt;
&lt;p&gt;この問題は旧型のTP-Linkルーターでは発生せず、WANポートに影響を与えずに自由に無効化できました。おそらく新型TP-Linkのプロダクトマネージャーは、これではWANポートが無駄になると考え、新型ルーターはすべてWAN/Lanポート混在型であるため、この問題が顕在化したのでしょう。&lt;/p&gt;
&lt;p&gt;数日前にMac miniのM4モデルが発表され、サイズがさらに小さく、消費電力も低くなったため、ネット上では再び「Mac miniをソフトウェアルーターとして利用し、Mac Surgeで家庭ネットワークを管理する」という風潮が広がっています。現在の私のネットワーク構成は非常に安定しており、1年以上新しいことを試していなかったので興味が湧きました。さらに、私のMac Studioも常時電源を切らないので、miniと同じようにソフトウェアルーターとして使えるのではないかと考えました。また、ネットユーザーたちが推奨するSurge（以下、Mac Surgeを指す）がDHCPサービスを管理することで、家中のデバイスが意識せずに魔法のようにインターネットに接続でき、各デバイスの接続状況を「エレガント」にリアルタイムで確認できるという点も魅力的でした。「エレガントは時代遅れにならない」という考えのもと、私はこのTP-Linkの問題を解決する方法を模索し始めました。&lt;/p&gt;
&lt;p&gt;ネットで検索した結果、例えば：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cn.v2ex.com/t/1053641&#34; target=&#34;_blank&#34;&gt; tp link 的路由器如何能在关闭 dhcp 服务的同时让 wan 口能够拨号上网？ - V2EX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;また：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.chiphell.com/forum.php?mod=viewthread&amp;tid=2521336&amp;highlight=&amp;mobile=no&#34; target=&#34;_blank&#34;&gt; 请教各位大佬关于华硕和tplink路由器关闭dhcp设置的问题 - 电脑讨论(新) -  Chiphell - 分享与交流用户体验&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;現状&#34;&gt;現状&lt;/h2&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 注意：操作前にTP-Link（以下、私のXDR-5480モデルを指す）の設定画面でルーター設定をバックアップしてください。操作ミスでルーターにアクセスできなくなった場合にリセットすると、ルーター設定が失われます。以下のように設定をエクスポートすればOKです。なお、エクスポートした設定にはポート設定とネットワーク設定は含まれません。この製品設計は、ネットワーク設定を間違えてリセットした後でも、設定をインポートすると間違った設定のままネットワークにアクセスできない状況を防ぐもので、TP-Linkのプロダクトマネージャーに拍手を送りたいです。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-80e6-9e16-eb66a08e2ff7.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ネットワークトポロジー図：&#34;&gt;ネットワークトポロジー図：&lt;/h3&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-8003-89a9-e3f05024c8b5.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;目標&#34;&gt;目標&lt;/h3&gt;
&lt;p&gt;現在のすべてのデバイスの接続方法やネットワークセグメントを変更せず（怒られるのが怖いので）、Mac StudioのSurgeをゲートウェイとしてDHCPサービスを管理させる。&lt;/p&gt;
&lt;h3 id=&#34;難点&#34;&gt;難点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;TP-Linkが自身のDHCPサービスを無効にすると、すべてのポート（SPFポートを含む）がLanポートになり、ポートアドレスをカスタマイズできなくなるという警告が表示されます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TP-Linkが自身のDHCPサービスを無効にすると、現在すべてのLanポートのIPアドレスはフロントエンドルーター（つまり光モデム）から取得されるという警告が表示されます。これは純粋なAPとしての動作なので当然ですが、Surgeが光モデム上に存在するDHCPサービスを検知してしまう原因になります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac Surgeをゲートウェイとして使用する場合、自身でDHCPサービスを開始し、ネットワーク上に他のDHCPサービスが存在しないことを要求します。そうでない場合、競合が発生して接続が切断される可能性があります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第2点と第3点から、光モデムのDHCPとルーターのDHCPサービスの両方を無効にする必要があります。しかし！この操作を行う前に光モデム/ルーターでIPとMACアドレスのバインド設定をしていないと、WiFiで両者に接続できなくなり、ルーターと光モデムをリセットするしかなくなります！（どうして知っているかは聞かないでください）したがって、光モデムのDHCPサービスを無効にすることはできません。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;解決方法&#34;&gt;解決方法&lt;/h2&gt;
&lt;p&gt;上記の目標と難点を踏まえて、「皆さん、メモを取ってください。私は以下のように配置を調整します」：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-80ce-8790-d3cef3ef7d8f.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ステップ1：光モデムの電源を切る&#34;&gt;ステップ1：光モデムの電源を切る&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; 実際には光モデムとTP-Linkの接続を切断するだけで十分です。ここで電源を切るように指示しているのは、誤って光モデムのWiFiに接続してしまうのを防ぐためです。光モデムのWiFiを忘れるように設定している場合は、電源を切らずにTP-Linkとの接続を切断するだけでOKです。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;最初に光モデムの設定を行わず、そのDHCPサービスがSurgeに検出されてSurgeがDHCPサービスを開始できないようにします。また、すでに光モデムとTP-Linkの接続を切断しているため、次のステップでTP-LinkのDHCPサービスを無効にした場合、TP-Linkは自ら上位ルーターのDHCPサービスを検出してLanポートのIPを変更することはありません。&lt;/p&gt;
&lt;h3 id=&#34;ステップ2：ルーターのdhcpサービスを無効化&#34;&gt;ステップ2：ルーターのDHCPサービスを無効化&lt;/h3&gt;
&lt;p&gt;設定画面で無効にするだけで、ここでは「オフ」を選択します。設定が成功した後、改めて「自動」に変更します。自動に変更するのはネットワークの堅牢性のためで、後ほど説明します。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-804e-a69d-edb6a6eaabc1.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ステップ3：surge-dhcpを有効化&#34;&gt;ステップ3：Surge DHCPを有効化&lt;/h3&gt;
&lt;p&gt;この手順はSurgeの「概要」と「デバイス」タブのどちらからもアクセスできます：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-8091-83b9-e144224f35d5.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;SurgeがMacのIPアドレスを手動設定かつ固定に変更することを通知してきます。ここでは&lt;code&gt;192.168.5.100&lt;/code&gt;となります。具体的なチュートリアルはネット上に多数ありますので、ここでは詳細は省きます。&lt;/p&gt;
&lt;p&gt;注意点として、ルーターのアドレスが&lt;code&gt;192.168.5.1&lt;/code&gt;と表示され、アドレスプールが&lt;code&gt;192.168.5.100&lt;/code&gt;から&lt;code&gt;192.168.5.200&lt;/code&gt;までとなっています。私はアドレスプールを&lt;code&gt;192.168.5.2&lt;/code&gt;から&lt;code&gt;192.168.5.254&lt;/code&gt;に変更し、範囲を広げました。&lt;/p&gt;
&lt;h3 id=&#34;ステップ4：新しいルーターアドレスを確認&#34;&gt;ステップ4：新しいルーターアドレスを確認&lt;/h3&gt;
&lt;p&gt;Surgeの設定後、ルーターの&lt;code&gt;192.168.5.1&lt;/code&gt;にアクセスすると接続できない状態になります！慌てる必要はありません。この時点でMac StudioがDHCPサービスを提供しており、TP-Linkルーターに新しいIPアドレスを割り当てるからです（なぜこうなるのかは不明です）。「デバイス」をクリックし、「Hostname Unsuitable for Printing」という名前のデバイス（必ずしもこの名前とは限りません）を見つけ、アドレスバーからアクセスするとお馴染みのルーター画面が表示されます。ここでの新しいルーターIPアドレスは&lt;code&gt;192.168.5.114&lt;/code&gt;でした。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-809d-894e-fbe831126b06.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ステップ5：ルーターのlanポート設定とpppoe接続&#34;&gt;ステップ5：ルーターのLanポート設定とPPPoE接続&lt;/h3&gt;
&lt;p&gt;この時点ではインターネットに接続できません。光モデムの電源が入っていないからです！このステップで光モデムの電源を入れ、数分待った後、ルーターの設定画面で&lt;code&gt;Wan 口已经断开连接&lt;/code&gt;をクリックしても反応がない状態になります。&lt;/p&gt;
&lt;p&gt;しかし諦めないでください！現在のStudioの役割は、ソフトウェアルーターを設定する場合と似ていることに気付くでしょう。以前は光モデムがPPPoE接続を担当し、ソフトウェアルーターがメインルーターや光モデムに接続されてDHCPサービスを提供していました。現在は、PPPoE接続デバイスをルーターに移行し、Studioがメインルーターに接続されているため、StudioがソフトウェアルーターとしてDHCPサービスを提供する形になります。&lt;/p&gt;
&lt;p&gt;重要なのはこのステップ：TP-LinkのLanポートIPアドレスを手動で&lt;code&gt;192.168.5.1&lt;/code&gt;に設定することです（そうしないとネットワーク上に&lt;code&gt;192.168.5.1&lt;/code&gt;というIPアドレスを持つデバイスが存在しなくなります）。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-80e0-8bb3-f208b1f9c874.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;LanポートIPを手動設定後（Lanポートと呼びますが、光モデムに接続されておりPPPoE接続が可能です！）、インターネット設定に戻り「接続」をクリックします。初回の接続には時間がかかるため、4、5回クリックする必要があるかもしれませんが、最終的には成功します。&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-8092-a5bc-cc3e8f728305.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ステップ6：最終設定&#34;&gt;ステップ6：最終設定&lt;/h3&gt;
&lt;p&gt;これで設定は完了です。接続済みのデバイスを右クリックし、「Surgeをゲートウェイとして設定」を選択後、デバイスをネットワークに再接続してください：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-8044-b913-da4aafc3219f.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;さらに「新しいデバイスには自動的にSurgeをデフォルトゲートウェイとして設定」も有効にしておきます：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-80fc-9142-f5520e0a2756.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;これで全てのデバイスがSurgeをゲートウェイとして使用し、リアルタイムのトラフィックを監視できるようになります。&lt;/p&gt;
&lt;p&gt;ステップ2でTP-LinkのDHCPサービスを無効にした件を覚えていますか？この時点でTP-Linkに戻り、DHCPサービスを「自動」に変更できます。これは万が一**SurgeのDHCPサービスがクラッシュしたり、Macが故障した場合でも、あなたと家族のデバイスがネットワークにアクセスできるようにするためです。そうすれば、あなたは叱られずに済みます！**TP-Linkのこの設定は「自動」でLAN内のDHCPサービスを検出し、存在しない場合は自身のDHCPを有効に、存在する場合は無効にします：&lt;/p&gt;
&lt;p caption=&#39;&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2024/how-to-pppoe-after-close-tp-link-dhcp/134800e8-7a61-805c-98c5-e3895ef7dfe0.webp&#39; alt=&#39;&#39; title=&#39;&#39;&gt;&lt;/p&gt;
&lt;p&gt;注：「オフ」を選択して保存すると、ルーターのアドレスが再び&lt;code&gt;192.168.5.114&lt;/code&gt;に変更されます。また、設定変更ができなくなります（光モデムに接続した状態でDHCPを無効にすると、前述の問題1と2が発生するため）、その場合は最初から（光モデムの電源を切って）手順をやり直す必要があります。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;これで全て完了です。この過程でいくつかの奇妙な問題に遭遇し、失敗した試みもありました。例えば、なぜ光モデムの電源を切ってルーターを設定した後で再び電源を入れる方法を思いついたのか、想像できるでしょうか？&lt;/p&gt;
&lt;p&gt;皆さんがWiFi自由を手に入れられますように！&lt;/p&gt;
</description>
            <pubDate>Mon, 04 Nov 2024 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/how-to-pppoe-after-close-tp-link-dhcp.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/how-to-pppoe-after-close-tp-link-dhcp.html</guid>
            
                <category>折腾</category>
            
                <category>软路由</category>
            
                <category>网络</category>
            
                <category>路由器</category>
            
                <category>技巧</category>
            
                <category>技术</category>
            
                <category>旁路由</category>
            
                <category>千兆</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>Notion Flow モジュールを使用して変換する方法</title>
            <description>&lt;p&gt;一週間前に、私はNotion Flowブラウザ拡張機能を構築しました：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://twitter.com/_Xheldon/status/1770466495560294583&#34; target=&#34;_blank&#34;&gt; Xheldon on Twitter / X&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そして先日更新された0.4.1バージョンでは：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://notion-flow.xheldon.com/blog/2024/03/31/0.4.1&#34; target=&#34;_blank&#34;&gt; 0.4.1 | Notion Flow&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AWS S3 API互換の自社OSSサービス（Cloudflare R2など）をサポートしました：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cloudflare.com/zh-cn/developer-platform/r2/&#34; target=&#34;_blank&#34;&gt; Cloudflare R2 | 零出口费用分布式对象存储 | Cloudflare | Cloudflare&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本記事では、このブラウザ拡張機能をGithub Jekyllブログでどのように使用しているか簡単に紹介します。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Jekyll静的ブログはRubyで構築されており、プラグインをサポートしています。そのため、私はLiquidテンプレート言語を処理するためにいくつかのプラグインを自作しました（Jekyllブログのプラグインは&lt;code&gt;_plugins&lt;/code&gt;ディレクトリに配置され、rubyファイルを記述後、このディレクトリに配置してサービスを再起動するだけで機能します）。コンテンツはNotion Flowで変換されたNotionの内容から取得しています。例えば、ブックマークを処理するプラグインの内容は以下の通りです：&lt;/p&gt;


&lt;figure class=&#34;highlight ruby&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;50&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;51&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;52&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;53&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;54&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;55&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;56&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;57&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs ruby&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;RenderBookMarkBlock&lt;/span&gt; &amp;lt; &lt;span class=&#34;hljs-title class_ inherited__&#34;&gt;Liquid::Block&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;initialize&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;tag_name, attr, tokens&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-comment&#34;&gt;# 普通的链接没有 yid 和 bid&lt;/span&gt;&lt;br&gt;            attrs = attr.scan(&lt;span class=&#34;hljs-regexp&#34;&gt;/url\=\&amp;quot;(.*)\&amp;quot;\stitle\=\&amp;quot;(.*)\&amp;quot;\simg\=\&amp;quot;(.*)\&amp;quot;\syid\=\&amp;quot;(.*)\&amp;quot;\sbid\=\&amp;quot;(.*)\&amp;quot;/&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; !attrs.empty?&lt;br&gt;              &lt;span class=&#34;hljs-comment&#34;&gt;# 外部的 video 链接，youtube、bilibili（如本文上一篇博客就是）&lt;/span&gt;&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;3&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;4&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt; = (&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;)[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;].upcase&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@error&lt;/span&gt; = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt;&lt;br&gt;             &lt;span class=&#34;hljs-comment&#34;&gt;# 正常和 notion 一样的 bookmark（如本文上面三个链接就是）&lt;/span&gt;&lt;br&gt;                attrs = attr.scan(&lt;span class=&#34;hljs-regexp&#34;&gt;/url\=\&amp;quot;(.*)\&amp;quot;\stitle\=\&amp;quot;(.*)\&amp;quot;\simg\=\&amp;quot;(.*)\&amp;quot;/&lt;/span&gt;)&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;]&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt; = (&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;)[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;].upcase&lt;br&gt;                &lt;span class=&#34;hljs-variable&#34;&gt;@error&lt;/span&gt; = &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;render&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;context&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable&#34;&gt;@desc&lt;/span&gt; = &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; !&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;.&lt;span class=&#34;hljs-literal&#34;&gt;nil&lt;/span&gt;? &amp;amp;&amp;amp; !&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;.empty?&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;https://www.youtube.com/embed/&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@yid&lt;/span&gt;&amp;#125;&lt;/span&gt;?rel=0&amp;#x27; title=&amp;#x27;YouTube video player&amp;#x27; frameborder=&amp;#x27;0&amp;#x27; allow=&amp;#x27;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;elsif&lt;/span&gt; !&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;.&lt;span class=&#34;hljs-literal&#34;&gt;nil&lt;/span&gt;? &amp;amp;&amp;amp; !&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;.empty?&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p class=&amp;#x27;embed-responsive embed-responsive-16by9&amp;#x27; style=&amp;#x27;border-bottom: 1px solid #ddd;&amp;#x27;&amp;gt;&amp;lt;iframe src=&amp;#x27;//player.bilibili.com/player.html?bvid=&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@bid&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;amp;high_quality=1&amp;amp;as_wide=1&amp;#x27; scrolling=&amp;#x27;no&amp;#x27; border=&amp;#x27;0&amp;#x27; frameborder=&amp;#x27;no&amp;#x27; framespacing=&amp;#x27;0&amp;#x27; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt;&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p&amp;gt;&amp;lt;a class=&amp;#x27;link-bookmark&amp;#x27; href=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; target=&amp;#x27;_blank&amp;#x27;&amp;gt;&amp;lt;span data-bookmark-img=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; data-bookmark-title=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@firstChar&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27;&amp;gt;&amp;lt;img src=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27;/&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@title&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@desc&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@url&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;# 上传的 video&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;module&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;hljs-title class_&#34;&gt;RenderVideoBlock&lt;/span&gt; &amp;lt; &lt;span class=&#34;hljs-title class_ inherited__&#34;&gt;Liquid::Block&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;initialize&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;tag_name, attr, tokens&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            attrs = attr.scan(&lt;span class=&#34;hljs-regexp&#34;&gt;/caption\=\&amp;quot;(.*)\&amp;quot;\simg\=\&amp;quot;(.*)\&amp;quot;\ssuffix\=\&amp;quot;(.*)\&amp;quot;/&lt;/span&gt;)&lt;br&gt;            &lt;span class=&#34;hljs-variable&#34;&gt;@caption&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;]&lt;br&gt;            &lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;1&lt;/span&gt;]&lt;br&gt;            &lt;span class=&#34;hljs-variable&#34;&gt;@suffix&lt;/span&gt; = attrs[&lt;span class=&#34;hljs-number&#34;&gt;0&lt;/span&gt;][&lt;span class=&#34;hljs-number&#34;&gt;2&lt;/span&gt;]&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;render&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;context&lt;/span&gt;)&lt;br&gt;            text = &lt;span class=&#34;hljs-variable language_&#34;&gt;super&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;lt;p caption=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@caption&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27;&amp;gt;&amp;lt;video controls muted&amp;gt;&amp;lt;source src=&amp;#x27;&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@img&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; type=&amp;#x27;video/&lt;span class=&#34;hljs-subst&#34;&gt;#&amp;#123;&lt;span class=&#34;hljs-variable&#34;&gt;@suffix&lt;/span&gt;&amp;#125;&lt;/span&gt;&amp;#x27; /&amp;gt;&amp;lt;/video&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;end&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-title class_&#34;&gt;Liquid&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:Template&lt;/span&gt;.register_tag(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;render_bookmark&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:RenderBookMarkBlock&lt;/span&gt;)&lt;br&gt;&lt;span class=&#34;hljs-title class_&#34;&gt;Liquid&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:Template&lt;/span&gt;.register_tag(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;render_video&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-title class_&#34;&gt;Jekyll&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;hljs-symbol&#34;&gt;:RenderVideoBlock&lt;/span&gt;)&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;


&lt;p&gt;このロジックでは、NotionのブックマークモジュールのリンクがYoutubeやBilibiliの場合、埋め込み動画のHTML（iframe）に変換し、それ以外の場合はNotionブックマークに似たHTMLに変換します（CSSとの連携が必要です）。&lt;/p&gt;
&lt;p&gt;そのため、Notion Flowを使用してNotionコンテンツをMarkdown形式に変換する際に、ブックマークなどのモジュール変換ルールをカスタマイズし、ブログでYoutube、Bilibili、およびNotionと同じブックマークスタイルのコンテンツを表示できるようにしています。以下のようになります：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-attr&#34;&gt;video&lt;/span&gt;: &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;video&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;block&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (block.&lt;span class=&#34;hljs-property&#34;&gt;type&lt;/span&gt; === &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;file&amp;#x27;&lt;/span&gt;) &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-comment&#34;&gt;// 用户自己上传的 video 文件，用默认 video 插件处理&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&amp;#123;% render_video caption=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.caption&amp;#125;&lt;/span&gt;&amp;quot; img=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.url&amp;#125;&lt;/span&gt;&amp;quot; suffix=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.suffix&amp;#125;&lt;/span&gt;&amp;quot; %&amp;#125;\n![&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.caption&amp;#125;&lt;/span&gt;](&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.url&amp;#125;&lt;/span&gt;)\n&amp;#123;% endrender_video %&amp;#125;\n`&lt;/span&gt;;&lt;br&gt;  &amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (block.&lt;span class=&#34;hljs-property&#34;&gt;type&lt;/span&gt; === &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;external&amp;#x27;&lt;/span&gt;) &amp;#123;&lt;br&gt;    &lt;span class=&#34;hljs-comment&#34;&gt;// 外部链接、youtube 和 bilibili 视频链接，用 bookmark 处理&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;`&amp;#123;% render_bookmark url=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.url&amp;#125;&lt;/span&gt;&amp;quot; title=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;      block.caption || &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;#125;&lt;/span&gt;&amp;quot; img=&amp;quot;&amp;quot; yid=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;block.yid&amp;#125;&lt;/span&gt;&amp;quot; bid=&amp;quot;&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;      block.bid&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;    &amp;#125;&lt;/span&gt;&amp;quot; %&amp;#125;&amp;#123;% endrender_bookmark %&amp;#125;\n`&lt;/span&gt;;&lt;br&gt;  &amp;#125;&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;ここで注意が必要な点（私はrubyに詳しくありません）は、Liquidテンプレートのタグ間にテキストコンテンツが必須であること（空でも構いません）です。そうでない場合、rubyプラグインはHTMLを生成できません。つまり：&lt;/p&gt;


&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&amp;#123;% render_video  %&amp;#125;这里必须有任意内容！&amp;#123;% endrender_video %&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;


&lt;p&gt;このように、Rubyプラグインでは、&lt;code&gt;super&lt;/code&gt;変数に「ここには任意の内容が必要です！」という文が取得されます（この変数を使用しないことも可能です）。この内容がない場合、プラグインは何も返しません。&lt;/p&gt;
</description>
            <pubDate>Sun, 31 Mar 2024 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/how-i-use-notion-flow.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/how-i-use-notion-flow.html</guid>
            
                <category>教程</category>
            
                <category>技巧</category>
            
                <category>工作流</category>
            
                <category>技术</category>
            
                <category>Jekyll</category>
            
                <category>Notion</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>【動画】Notion Flowでブログ公開フローをシンプルに</title>
            <description>&lt;p&gt;この記事では、Notion Flowを使用してブログ公開プロセスを簡素化する方法を紹介する動画を共有します。詳細は公式サイトをご覧ください:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://notion-flow.xheldon.com&#34; target=&#34;_blank&#34;&gt; Notion Flow | Notion Flow&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;YouTube：&lt;/p&gt;
&lt;p class=&#39;embed-responsive embed-responsive-16by9&#39;&gt;&lt;iframe src=&#39;https://www.youtube.com/embed/aPitTcsruhM?rel=0&#39; title=&#39;YouTube video player&#39; frameborder=&#39;0&#39; allow=&#39;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#39; allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Bilibili：&lt;/p&gt;
&lt;p class=&#39;embed-responsive embed-responsive-16by9&#39; style=&#39;border-bottom: 1px solid #ddd;&#39;&gt;&lt;iframe src=&#39;//player.bilibili.com/player.html?bvid=BV1Ar421h7tM&amp;high_quality=1&amp;as_wide=1&#39; scrolling=&#39;no&#39; border=&#39;0&#39; frameborder=&#39;no&#39; framespacing=&#39;0&#39; allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;</description>
            <pubDate>Thu, 21 Mar 2024 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/tech/use-notion-flow.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/tech/use-notion-flow.html</guid>
            
                <category>折腾</category>
            
                <category>教程</category>
            
                <category>工作流</category>
            
                <category>技术</category>
            
                <category>插件</category>
            
                <category>视频</category>
            
                <category>Notion</category>
            
            
                <category>tech</category>
            
        </item>
        
        <item>
            <title>VSCodeをより使いやすくする設定——フロントエンド開発の視点から</title>
            <description>&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(241, 241, 239); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;☝🏻&lt;/span&gt;&lt;span&gt;後ほど動画で説明する予定です。設定の効果は実際に動きを見せないと違いが分かりにくいためで、ブログにGIFを作るのが面倒だからです。&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;フロントエンドの勉強を始めた頃、VSCodeはまだなく、WebStormを使っていました（当時学生で、違法コピーを使っていました）。すぐに使える体験は素晴らしかったです。しかし、オフィスPCのスペック低下、4Kやマルチディスプレイでのカクつき問題が長年解決されないこと、同僚の影響もあり、最終的に「設定の同期」機能が決め手となりVSCodeに移行しました。&lt;/p&gt;
&lt;p&gt;独立したホバー検索ボックスがないという重大な違和感に慣れた後、すぐに自分にとって使いやすい設定を見つけました。以下で詳しく説明します。もしもっと良い設定があると思われる方は、コメント欄に理由と効果のスクリーンショットを添えて教えてください。&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(241, 241, 239); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;📖&lt;/span&gt;&lt;span&gt;デフォルト設定は基本的に説明しません（特に便利な場合を除く）。デフォルトから変更した部分に焦点を当てます。VSCodeでは「右側のミニマップに現在行を表示するか」など、ほとんどの設定が変更可能で素晴らしいです。&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&#34;見た目&#34;&gt;見た目&lt;/h2&gt;
&lt;h3 id=&#34;テーマ-フォント&#34;&gt;テーマ/フォント&lt;/h3&gt;
&lt;p&gt;テーマはOne Dark Proを使用：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme&#34; target=&#34;_blank&#34;&gt; marketplace.visualstudio.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;フォントはFira Code：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/tonsky/FiraCode?tab=readme-ov-file#download--install&#34; target=&#34;_blank&#34;&gt; GitHub - tonsky/FiraCode: Free monospaced font with programming ligatures&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fira Codeは公式推奨フォントで、&lt;a href=&#34;https://code.visualstudio.com/docs/getstarted/tips-and-tricks#:~:text=zoomLevel%22%3A%205-,Font%20ligatures,-%22editor.fontFamily%22&#34;&gt;社内でも使用されています&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Fira Codeは特定の記号の変種サポートが優れており、&lt;code&gt;===&lt;/code&gt;や&lt;code&gt;&amp;lt;=&lt;/code&gt;などが美しく表示されます（一部は手動で文字セットと変種を有効にする必要があります）：&lt;/p&gt;
&lt;p caption=&#39;Fira Code 字体&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3371f847-fdd8-410c-82e1-b1d63cd91035.webp&#39; alt=&#39;Fira Code 字体&#39; title=&#39;Fira Code 字体&#39;&gt;&lt;/p&gt;
&lt;p&gt;Fira Codeのデフォルトの&lt;code&gt;&amp;amp;&lt;/code&gt;記号が苦手な人も多いですが、設定で変種を無効にできます。詳細はGitHubの説明を参照してください。私の設定は：&lt;/p&gt;
&lt;figure class=&#34;highlight json&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs json&#34;&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;workbench.colorTheme&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;One Dark Pro&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;editor.fontFamily&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;#x27;Fira Code&amp;#x27;, Monaco, &amp;#x27;Courier New&amp;#x27;, monospace&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;,&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;editor.fontLigatures&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;&amp;#x27;ss01&amp;#x27;, &amp;#x27;ss02&amp;#x27; off, &amp;#x27;ss03&amp;#x27;, &amp;#x27;ss04&amp;#x27;, &amp;#x27;ss05&amp;#x27;, &amp;#x27;ss07&amp;#x27;, &amp;#x27;cv29&amp;#x27;, &amp;#x27;cv28&amp;#x27;, &amp;#x27;cv13&amp;#x27;&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;また、行間は1.4、フォントサイズは13です。&lt;/p&gt;
&lt;h2 id=&#34;エディタ&#34;&gt;エディタ&lt;/h2&gt;
&lt;p&gt;最も重要なのがエディタ設定です。良いエディタはコーディング効率を上げるためにあります。以下で個別に説明します。&lt;/p&gt;
&lt;h3 id=&#34;空白文字の表示&#34;&gt;空白文字の表示&lt;/h3&gt;
&lt;p caption=&#39;Editor: Render Whitespace&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/9175365e-0357-4b2f-abf7-cdf20062b2ca.webp&#39; alt=&#39;Editor: Render Whitespace&#39; title=&#39;Editor: Render Whitespace&#39;&gt;&lt;/p&gt;
&lt;p&gt;私はデフォルトのselection設定を使用しています。つまり、選択範囲内に空白文字（スペース）がある場合のみ表示され、それ以外は表示されません。常に表示する&lt;code&gt;boundary&lt;/code&gt;設定は見た目が悪いです：&lt;/p&gt;
&lt;p caption=&#39;选区渲染空白符号&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/12c4e471-e6fc-4b6d-aed7-61d4db16cd18.webp&#39; alt=&#39;选区渲染空白符号&#39; title=&#39;选区渲染空白符号&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;自動で括弧を追加-削除&#34;&gt;自動で括弧を追加/削除&lt;/h3&gt;
&lt;p caption=&#39;Auto Closing 设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/49d09c46-5456-441a-9f72-fccc3a5d761e.webp&#39; alt=&#39;Auto Closing 设置&#39; title=&#39;Auto Closing 设置&#39;&gt;&lt;/p&gt;
&lt;p&gt;これらの設定は、開始括弧（&lt;code&gt;(&amp;#123;[&lt;/code&gt;など）を入力すると自動的に終了括弧（&lt;code&gt;)&amp;#125;]&lt;/code&gt;）が生成される機能です。削除時も同様にペアで削除されます。デフォルトでは挿入時にペア生成、削除時もペア削除です。&lt;/p&gt;
&lt;h3 id=&#34;括弧の色付け（プール）&#34;&gt;括弧の色付け（プール）&lt;/h3&gt;
&lt;p caption=&#39;Bracket Pair Colorization&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/899eeaba-8737-4f07-8e22-9480f915fcbc.webp&#39; alt=&#39;Bracket Pair Colorization&#39; title=&#39;Bracket Pair Colorization&#39;&gt;&lt;/p&gt;
&lt;p&gt;最初の設定を有効にすると、各括弧に色が付きます（白一色ではなく）。二つ目の設定を有効にすると、括弧の種類ごとに独立した色設定が適用されます（実際には異なる括弧でも色が重複しますが、表示順ではなく括弧種類ごとの順序で色付けされます——私の理解とテストによる）。&lt;/p&gt;
&lt;h3 id=&#34;矩形選択&#34;&gt;矩形選択&lt;/h3&gt;
&lt;p caption=&#39;Column Selection&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/c64604e0-b420-4845-86e2-bac8d40aaa3d.webp&#39; alt=&#39;Column Selection&#39; title=&#39;Column Selection&#39;&gt;&lt;/p&gt;
&lt;p&gt;デフォルトでは上から下に選択すると、行頭や行末を通過すると行全体が選択されます：&lt;/p&gt;
&lt;p caption=&#39;默认选中效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/d97e73d0-91ae-4e0a-befb-c708ceae1bc0.webp&#39; alt=&#39;默认选中效果&#39; title=&#39;默认选中效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;この設定を有効にすると、マウス選択が矩形選択になります（コード位置ではなくマウス位置に基づく選択）。JSONのキーなど、複数行の類似したインデントを同時編集する際に便利です：&lt;/p&gt;
&lt;p caption=&#39;列选择&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/99dcc5e1-65bd-4048-bf8a-b06443bc7745.webp&#39; alt=&#39;列选择&#39; title=&#39;列选择&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;列选择的一个应用场景&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/85a0ac88-34a6-4843-adfd-ea95f01c1806.gif&#39; alt=&#39;列选择的一个应用场景&#39; title=&#39;列选择的一个应用场景&#39;&gt;&lt;/p&gt;
&lt;p&gt;補足：ターミナルで選択中にOptキーを押すと同様の効果が得られます。&lt;/p&gt;
&lt;h3 id=&#34;コピー時にシンタックスハイライトを保持&#34;&gt;コピー時にシンタックスハイライトを保持&lt;/h3&gt;
&lt;p caption=&#39;Copy With Syntax Highlighting&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2e507e99-524a-41c0-978c-42cb1bcbebca.webp&#39; alt=&#39;Copy With Syntax Highlighting&#39; title=&#39;Copy With Syntax Highlighting&#39;&gt;&lt;/p&gt;
&lt;p&gt;リッチテキストエディタによっては特別な処理がなく、VSCodeから直接コードをコピーすると色情報も一緒にコピーされてしまいます。これは通常望ましくありません。この設定で色なしでコピーできます。&lt;/p&gt;
&lt;h3 id=&#34;ドラッグ操作&#34;&gt;ドラッグ操作&lt;/h3&gt;
&lt;p caption=&#39;Drag And Drop&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/319dae0d-0369-4469-abd9-ed2e0c36649c.webp&#39; alt=&#39;Drag And Drop&#39; title=&#39;Drag And Drop&#39;&gt;&lt;/p&gt;
&lt;p&gt;私は長年コーディングしてきましたが、「ドラッグ」でコードブロックを移動する操作はほとんど使わないので、無効化を推奨します。二つ目の設定は、shiftを押しながらファイルをVSCodeにドラッグすると、メディアファイルの場合ファイル名のみ表示され、shiftなしでドラッグするとメディアファイルが開きます。予期せぬ用途に備えて便利です（デフォルトで有効）。&lt;/p&gt;
&lt;h3 id=&#34;空選択時の現在行コピー&#34;&gt;空選択時の現在行コピー&lt;/h3&gt;
&lt;p caption=&#39;Empty Selection Clipboard&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/32f95652-6320-4347-8c9e-b7f03dbecd79.webp&#39; alt=&#39;Empty Selection Clipboard&#39; title=&#39;Empty Selection Clipboard&#39;&gt;&lt;/p&gt;
&lt;p&gt;選択範囲がなくカーソルだけの状態でコピー操作をすると、現在行全体が選択されます。現在行のコピーが簡単になります（デフォルトで有効）。&lt;/p&gt;
&lt;h3 id=&#34;自動折りたたみ&#34;&gt;自動折りたたみ&lt;/h3&gt;
&lt;p caption=&#39;Folding&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/96927f79-74ed-4949-b3e0-7cff488269ed.webp&#39; alt=&#39;Folding&#39; title=&#39;Folding&#39;&gt;&lt;/p&gt;
&lt;p&gt;コード折りたたみは確実に必要です。折りたたみ範囲のハイライトも必要です（マウスが行を通過する効果や現在行のハイライトと同様）。そうしないと、現在の行が折りたたまれているかどうか分かりません。最後に、import部分の自動折りたたみは不要だと思います。&lt;/p&gt;
&lt;p&gt;折りたたみに関しては、私は常に表示される設定を好みます。この機能は非常に頻繁に使用するため、毎回ホバーして折りたたまれている行を確認し、クリックして展開するのは効率が悪いからです。一目でどこが折りたたまれているか分かるようにしたいので、alwaysに設定する必要があります：&lt;/p&gt;
&lt;p caption=&#39;Show Folding Controls&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/0a382e11-522d-490a-a086-703b291ef90e.webp&#39; alt=&#39;Show Folding Controls&#39; title=&#39;Show Folding Controls&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;括弧-インデントガイド&#34;&gt;括弧/インデントガイド&lt;/h3&gt;
&lt;p caption=&#39;（缩进/括号）参考线&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b537a5b7-b989-4346-837b-919a4705599c.webp&#39; alt=&#39;（缩进/括号）参考线&#39; title=&#39;（缩进/括号）参考线&#39;&gt;&lt;/p&gt;
&lt;p&gt;以下の図のようになりますが、「インデントガイド」が何かテストできなかったので、とりあえず有効にします。&lt;/p&gt;
&lt;p caption=&#39;图中高亮的括号&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f8b0495e-2bd6-4dd5-9eb1-36a33821f1e8.webp&#39; alt=&#39;图中高亮的括号&#39; title=&#39;图中高亮的括号&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ホバー時のポップアップ表示位置&#34;&gt;ホバー時のポップアップ表示位置&lt;/h3&gt;
&lt;p caption=&#39;Hover 位置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/da26e746-9e8b-4a3a-9b24-2a38abae431d.webp&#39; alt=&#39;Hover 位置&#39; title=&#39;Hover 位置&#39;&gt;&lt;/p&gt;
&lt;p&gt;通常、コードは上から下に読んでいくため、この設定ではコードをホバーした際にポップアップが上に表示され、内容が遮られます。ポップアップを消して再表示させるためにマウスを動かす必要があり、お勧めしません。&lt;/p&gt;
&lt;p caption=&#39;始终显示提示在下方更合适&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6df3c907-16b9-4cba-b7f3-daa4a5fd4532.webp&#39; alt=&#39;始终显示提示在下方更合适&#39; title=&#39;始终显示提示在下方更合适&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;ホバー時のヒント表示&#34;&gt;ホバー時のヒント表示&lt;/h3&gt;
&lt;p caption=&#39;消失延迟其实不需要&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6b18c5da-1193-4e89-b49f-b7775dcdb192.webp&#39; alt=&#39;消失延迟其实不需要&#39; title=&#39;消失延迟其实不需要&#39;&gt;&lt;/p&gt;
&lt;p&gt;マウスを外した時は表示したくないので、直接0に設定します。&lt;/p&gt;
&lt;h3 id=&#34;マウスでのフォントサイズ変更&#34;&gt;マウスでのフォントサイズ変更&lt;/h3&gt;
&lt;p caption=&#39;完全没用的功能…&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2e05860a-01cb-45ff-9d3b-230d8871ebd6.webp&#39; alt=&#39;完全没用的功能…&#39; title=&#39;完全没用的功能…&#39;&gt;&lt;/p&gt;
&lt;p&gt;誤操作が多いので無効にします。&lt;/p&gt;
&lt;h3 id=&#34;エディター領域上部のパディング&#34;&gt;エディター領域上部のパディング&lt;/h3&gt;
&lt;p caption=&#39;统一视觉间隔&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/07183c4a-3dcc-412d-a7bb-f5167443874d.webp&#39; alt=&#39;统一视觉间隔&#39; title=&#39;统一视觉间隔&#39;&gt;&lt;/p&gt;
&lt;p&gt;私は2に設定しています。下部のパディングは不要です。&lt;/p&gt;
&lt;p caption=&#39;优雅，永不过时&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/9f1cd71d-f579-44c6-8b23-58f558dfeeaf.webp&#39; alt=&#39;优雅，永不过时&#39; title=&#39;优雅，永不过时&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;スクロールバー&#34;&gt;スクロールバー&lt;/h3&gt;
&lt;p&gt;水平スクロールバーは幅6、垂直は25（デフォルトは水平12、垂直14）：&lt;/p&gt;
&lt;p caption=&#39;Scrollbar&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/2b7e8382-836f-4fe4-a7b5-c88e24332838.webp&#39; alt=&#39;Scrollbar&#39; title=&#39;Scrollbar&#39;&gt;&lt;/p&gt;
&lt;p&gt;私はスクロール範囲外に移動する機能が好きではなく、1画面で完全に表示できる内容でもスクロールバーが表示されてしまうため、最後の「Scroll Beyond Last Line」は無効にしています。&lt;/p&gt;
&lt;p caption=&#39;滚动条显示信息&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/361fa784-0d98-4055-a56e-58678f0c3a31.webp&#39; alt=&#39;滚动条显示信息&#39; title=&#39;滚动条显示信息&#39;&gt;&lt;/p&gt;
&lt;p&gt;垂直スクロールバーを20に大きくした理由は、その領域にはスクロールバーだけでなく3つの情報が含まれているからです：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;スクロールバー右側の明るい黄色はエディターの警告情報です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スクロールバー中央の暗い黄色ブロックは検索にマッチした項目（グローバル検索と現在のエディター検索を含む）です。暗い黄色ブロックは灰色（カーソルで選択された部分や類似内容）や薄いピンク（カーソルで選択された内容の宣言部分）の場合もあります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スクロールバー全体にわたる青い線はカーソルがある行です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スクロールバー左側の緑色部分はコードが変更された部分です。Gitを有効にしている場合、薄い黄色（変更部分）になることもあります。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;このように情報表示が豊富なため、幅を広くしています。&lt;/p&gt;
&lt;h3 id=&#34;スムーズスクロール&#34;&gt;スムーズスクロール&lt;/h3&gt;
&lt;p caption=&#39;动画，优雅&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/190452c5-f985-47b4-b238-000edce28c4b.webp&#39; alt=&#39;动画，优雅&#39; title=&#39;动画，优雅&#39;&gt;&lt;/p&gt;
&lt;p&gt;強く推奨します。これにより、スクロール時にどのくらい行が移動したか分かり、突然ジャンプして「どこにスクロールしたか分からない」ということがなくなります。&lt;/p&gt;
&lt;h3 id=&#34;スクロール固定&#34;&gt;スクロール固定&lt;/h3&gt;
&lt;p caption=&#39;吸顶，好用&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/37741a88-7ba7-481a-9fe5-06ed276af9d3.webp&#39; alt=&#39;吸顶，好用&#39; title=&#39;吸顶，好用&#39;&gt;&lt;/p&gt;
&lt;p&gt;スクロール時に現在の画面外のスコープを確認する必要がある場合、このオプションを有効にします。また、水平スクロール時にsticky関数がスクロールされてしまうため、私はスクロールさせない設定を好みます。最後のオプションは無効にします。&lt;/p&gt;
&lt;p caption=&#39;左右滚动不跟随&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b7b7e17c-ac89-4d69-b1c2-648f0e582a40.webp&#39; alt=&#39;左右滚动不跟随&#39; title=&#39;左右滚动不跟随&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;カーソル&#34;&gt;カーソル&lt;/h3&gt;
&lt;p caption=&#39;Cursor Blinking&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5736c4cc-e07c-40f1-ae31-e1c16e458a00.webp&#39; alt=&#39;Cursor Blinking&#39; title=&#39;Cursor Blinking&#39;&gt;&lt;/p&gt;
&lt;p&gt;1つ目はカーソルの点滅効果、2つ目は異なる位置をクリックした際にカーソルが前の位置からアニメーションで移動する効果です。これにより、今回のクリック位置が前の編集位置からどこにあるか分かり、情報が豊富になります。&lt;/p&gt;
&lt;h3 id=&#34;検索&#34;&gt;検索&lt;/h3&gt;
&lt;p caption=&#39;编辑器右上角查找小部件&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/eb174538-47bb-44b8-ba84-54df4a37555e.webp&#39; alt=&#39;编辑器右上角查找小部件&#39; title=&#39;编辑器右上角查找小部件&#39;&gt;&lt;/p&gt;
&lt;p&gt;これは無効にすることをお勧めします。検索時に無効にしていないと、ファイル上部に余分なスペースが生じ、検索ボックスを閉じるとエディターが跳ねるように動いてしまいます。&lt;/p&gt;
&lt;p caption=&#39;空白，不优雅&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/83dcf800-6ec9-4a8a-8b49-2e69e419bd72.webp&#39; alt=&#39;空白，不优雅&#39; title=&#39;空白，不优雅&#39;&gt;&lt;/p&gt;
&lt;p&gt;ただし、このオプションを有効にするとエディター内容が遮られる可能性があるため、各自で判断してください（通常、上部はimport後の改行内容なので、遮られても問題ありません）。&lt;/p&gt;
&lt;p caption=&#39;没空白，优雅&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6878a013-d547-4ccb-9792-32e03a97e9d4.webp&#39; alt=&#39;没空白，优雅&#39; title=&#39;没空白，优雅&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;検索ウィジェットへの自動入力&#34;&gt;検索ウィジェットへの自動入力&lt;/h3&gt;
&lt;p caption=&#39;自动带入，优雅&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f671a305-d7c8-4ae0-b91c-5aa094bbd3a6.webp&#39; alt=&#39;自动带入，优雅&#39; title=&#39;自动带入，优雅&#39;&gt;&lt;/p&gt;
&lt;p&gt;これは無効にすることをお勧めします。検索後に特定の内容を選択し、さらに別の内容を検索しようとすると、エディターが自動的に選択内容を検索ボックスに入力してしまい、前回の検索内容が消えてしまうからです。&lt;/p&gt;
&lt;h3 id=&#34;サムネイル&#34;&gt;サムネイル&lt;/h3&gt;
&lt;p caption=&#39;右侧小地图&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b8986040-1b86-4bbd-a99b-1b7d551c8b28.webp&#39; alt=&#39;右侧小地图&#39; title=&#39;右侧小地图&#39;&gt;&lt;/p&gt;
&lt;p&gt;エディター右側のサムネイルは常に表示しています。現在の編集位置や特定の関数・コンポーネントに対する相対位置を把握するために使用するため、サムネイルはスクロールせず、色ブロックのみをレンダリングする設定にしています。&lt;/p&gt;
&lt;h3 id=&#34;提案&#34;&gt;提案&lt;/h3&gt;
&lt;p caption=&#39;建议预览&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/1cbc255e-2784-461d-a723-ce5f325130a2.webp&#39; alt=&#39;建议预览&#39; title=&#39;建议预览&#39;&gt;&lt;/p&gt;
&lt;p&gt;このスイッチはデフォルトのまま無効にすることをお勧めします。Copilotの提案と混同する可能性があるためです。以下はCopilotの提案です：&lt;/p&gt;
&lt;p caption=&#39;copilot 建议&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/89587ee7-0329-43e7-9a68-814e55bd8e07.webp&#39; alt=&#39;copilot 建议&#39; title=&#39;copilot 建议&#39;&gt;&lt;/p&gt;
&lt;p&gt;そしてこれはプレビューの提案です：&lt;/p&gt;
&lt;p caption=&#39;整个一没必要咱就是说&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/26edace2-f059-4f51-a873-47a743946229.webp&#39; alt=&#39;整个一没必要咱就是说&#39; title=&#39;整个一没必要咱就是说&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;最近建议&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/203628d4-4e0c-4f9a-8289-31ab679750dc.webp&#39; alt=&#39;最近建议&#39; title=&#39;最近建议&#39;&gt;&lt;/p&gt;
&lt;p&gt;このオプションのデフォルトは「first」、つまり常に最初の提案を選択する設定ですが、私が頻繁に直面する問題は、CSSで&lt;code&gt;wid&lt;/code&gt;と入力した場合、当然&lt;code&gt;width&lt;/code&gt;を期待しているのに、&lt;code&gt;widow&lt;/code&gt;という提案が最初に表示されることです。この属性は使わないのですが、毎回最初に表示されるため、矢印キーで切り替える必要があります。そこで、ここは「最近使用したもの」に変更することを提案します。これは入力メソッドの「動的頻度調整」に似た機能です:&lt;/p&gt;
&lt;p caption=&#39;css 最近建议&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a1edc147-031b-4347-be78-8c6ec3c71bd7.webp&#39; alt=&#39;css 最近建议&#39; title=&#39;css 最近建议&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;ワークベンチ&#34;&gt;ワークベンチ&lt;/h2&gt;
&lt;h3 id=&#34;コマンドパレット&#34;&gt;コマンドパレット&lt;/h3&gt;
&lt;p caption=&#39;命令建议&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a62c1989-314d-4675-abbb-cb9f09534480.webp&#39; alt=&#39;命令建议&#39; title=&#39;命令建议&#39;&gt;&lt;/p&gt;
&lt;p&gt;同じコマンドを繰り返し入力することが多いため、コマンド履歴リストを開くのは便利です。また、入力内容を保持する機能も有用です。例えば「Toggle Screen Capture Mode」のような「toggle」で始まるコマンドの場合です。&lt;/p&gt;
&lt;p&gt;注意点として、入力後にescキーを押して入力ボックスを閉じた場合、次回呼び出した時に入力内容は保持されません。コマンドを選択して実行した後、再度呼び出すと前回の入力内容が保持されます。&lt;/p&gt;
&lt;h3 id=&#34;エクスプローラーツリー&#34;&gt;エクスプローラーツリー&lt;/h3&gt;
&lt;p caption=&#39;目录树滚动&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ff187f9a-5588-40fb-927d-89e701495d94.webp&#39; alt=&#39;目录树滚动&#39; title=&#39;目录树滚动&#39;&gt;&lt;/p&gt;
&lt;p&gt;アニメーションは通常有効にしています。「優雅さは永遠に色褪せない」からです。この設定は「設定」画面のスクロールにも影響します（以前はエディター設定のスムーススクロールが「設定」画面やエクスプローラーツリーのスクロールに影響しませんでした）。&lt;/p&gt;
&lt;h3 id=&#34;クイックオープン履歴&#34;&gt;クイックオープン履歴&lt;/h3&gt;
&lt;p caption=&#39;快速打开带入上次记录&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b4633d53-e671-437c-a4e9-241fe722c953.webp&#39; alt=&#39;快速打开带入上次记录&#39; title=&#39;快速打开带入上次记录&#39;&gt;&lt;/p&gt;
&lt;p&gt;cmd + pを押すとクイックオープン入力ボックスが表示されます。履歴を記憶するのは良い機能です。また、フォーカスが外れた時に自動的に消えるかどうかのオプションもあります。ほとんどの場面では自動的に消える方が良いですが、稀に必要ない場合もあるため、デフォルトの自動消去を維持しています。&lt;/p&gt;
&lt;h3 id=&#34;ワークベンチのアニメーション効果軽減&#34;&gt;ワークベンチのアニメーション効果軽減&lt;/h3&gt;
&lt;p caption=&#39;绝不减少动画&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/24d1bc51-76bf-415b-9c79-561bc6eb7caf.webp&#39; alt=&#39;绝不减少动画&#39; title=&#39;绝不减少动画&#39;&gt;&lt;/p&gt;
&lt;p&gt;64GBメモリのM1 Maxではアニメーションを減らす必要はありません（デフォルトはautoで、システム構成に応じて自動調整されます。複数のコンピューター間で設定を同期する問題に対応しています）。&lt;/p&gt;
&lt;h3 id=&#34;フォントスムージング&#34;&gt;フォントスムージング&lt;/h3&gt;
&lt;p caption=&#39;字体平滑&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/093ce91b-5349-48a0-b563-2a44726f3bf2.webp&#39; alt=&#39;字体平滑&#39; title=&#39;字体平滑&#39;&gt;&lt;/p&gt;
&lt;p&gt;CSSの&lt;code&gt;-webkit-font-smoothing: antialiased;&lt;/code&gt;に似ています。defaultはほとんどの非Retinaディスプレイで最もシャープなフォント表示（サブピクセルレベル）を行い、antialiasedはピクセルレベルのスムージングで、フォントが細くなる可能性があります。図を参照:&lt;/p&gt;
&lt;p caption=&#39;default 设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/81378425-4fd6-4954-8d27-5317c822b237.webp&#39; alt=&#39;default 设置&#39; title=&#39;default 设置&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;antialiased 设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/e24ea63a-7536-48bd-8dec-302b335224a9.webp&#39; alt=&#39;antialiased 设置&#39; title=&#39;antialiased 设置&#39;&gt;&lt;/p&gt;
&lt;p&gt;この設定は「ワークベンチ」ブロックにありますが、エディター領域にも影響します。antialiasedを有効にすると、エディター領域とワークベンチ領域の両方でフォントがより暗く（コントラストが弱く）、細くなることがわかります。私は後者が好きなので有効にしています。&lt;/p&gt;
&lt;p&gt;注意点として、「サブピクセルレベル」とはピクセルよりも小さいレベルという意味ではなく、「ピクセルに至らない」レベル、つまりより低いレベルを指し、より高いレベルではありません。&lt;/p&gt;
&lt;h3 id=&#34;エクスプローラーツリーのsticky&#34;&gt;エクスプローラーツリーのsticky&lt;/h3&gt;
&lt;p caption=&#39;目录树滚动吸顶&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ed8074f7-0e31-4a1f-80f8-1618d2264e73.webp&#39; alt=&#39;目录树滚动吸顶&#39; title=&#39;目录树滚动吸顶&#39;&gt;&lt;/p&gt;
&lt;p&gt;非常に便利で、スクロール時に現在のスクロールパスを確認できます。唯一の欠点はbox-shadowを追加できればより区別しやすくなることです:&lt;/p&gt;
&lt;p caption=&#39;目录树吸顶效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5a7c2102-2730-47a0-b225-738a42d86342.webp&#39; alt=&#39;目录树吸顶效果&#39; title=&#39;目录树吸顶效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;stickyの最大レベルも変更可能で、デフォルトは7で十分です（エディターのstickyデフォルトは5レベル）。&lt;/p&gt;
&lt;p&gt;注意点として、この設定は「設定」画面にも適用されます（設定画面はエディターではなくワークベンチに属していることがわかりました）:&lt;/p&gt;
&lt;p caption=&#39;设置项界面也归它管&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/031c3170-cd43-4775-8401-a95e6c474a75.webp&#39; alt=&#39;设置项界面也归它管&#39; title=&#39;设置项界面也归它管&#39;&gt;&lt;/p&gt;
&lt;p&gt;エクスプローラーツリーのインデントは14に変更しました。ガイドラインは常に表示するようにしています。同レベルのファイルが多すぎると見つけにくいためです:&lt;/p&gt;
&lt;p caption=&#39;目录树缩进&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/7a67020e-c5a4-4114-9ac0-ff3afcb5cb61.webp&#39; alt=&#39;目录树缩进&#39; title=&#39;目录树缩进&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;アウトラインナビゲーション&#34;&gt;アウトラインナビゲーション&lt;/h3&gt;
&lt;p caption=&#39;目录导航显示 icon&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/eae4d00a-68d6-4c64-bab8-34df8fc7f458.webp&#39; alt=&#39;目录导航显示 icon&#39; title=&#39;目录导航显示 icon&#39;&gt;&lt;/p&gt;
&lt;p&gt;アウトラインナビゲーションは必要ですが、ファイル/フォルダアイコンは不要です。これにより、ファイル内の配列やクラスと明確に区別でき、非常に便利です:&lt;/p&gt;
&lt;p caption=&#39;面包屑显示效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/57e4fefd-4c76-42cd-b79c-d3d49eb2d1df.webp&#39; alt=&#39;面包屑显示效果&#39; title=&#39;面包屑显示效果&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;変更されたタブ&#34;&gt;変更されたタブ&lt;/h3&gt;
&lt;p&gt;これに関連する設定が複数あります。例えば、変更後保存されていないファイルのタブ上部にハイライト線を表示する設定:&lt;/p&gt;
&lt;p caption=&#39;高亮修改的 tab&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/e4a60c98-ec6f-452d-84ea-e0835ed963bf.webp&#39; alt=&#39;高亮修改的 tab&#39; title=&#39;高亮修改的 tab&#39;&gt;&lt;/p&gt;
&lt;p&gt;デフォルトでは点が表示されますが、このオプションを有効にすると点と線の両方が表示されます。エディターを再起動すると青い線のみが表示されます（バグかもしれません。再起動しなくても有効になるべきです）。&lt;/p&gt;
&lt;p&gt;効果:&lt;/p&gt;
&lt;p caption=&#39;修改过的 tab 效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/aea54cb4-158e-4662-a6b5-285fc56fd836.webp&#39; alt=&#39;修改过的 tab 效果&#39; title=&#39;修改过的 tab 效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;「点」もタブのスペースの一部を占有するため、より多くのタブ内容情報を表示できなくなります。そのため、このオプションを有効にすることをお勧めします。&lt;/p&gt;
&lt;h3 id=&#34;マウスナビゲーション&#34;&gt;マウスナビゲーション&lt;/h3&gt;
&lt;p caption=&#39;鼠标前进后退&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/254a8290-8b0a-4ebc-ac36-d453a855719d.webp&#39; alt=&#39;鼠标前进后退&#39; title=&#39;鼠标前进后退&#39;&gt;&lt;/p&gt;
&lt;p&gt;これはデフォルトオプションですが、説明しておきます。左側にボタン（右手用の4、5ボタン）があるマウスでは、直接ナビゲーションに使用でき、非常に便利です。&lt;/p&gt;
&lt;h3 id=&#34;タブの固定&#34;&gt;タブの固定&lt;/h3&gt;
&lt;p caption=&#39;允许 tab 固定，好用&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b8c68b52-f2ec-4fb4-ac39-1fd1af2c9ebd.webp&#39; alt=&#39;允许 tab 固定，好用&#39; title=&#39;允许 tab 固定，好用&#39;&gt;&lt;/p&gt;
&lt;p&gt;固定されたタブはデフォルトでエディターグループの左側に表示されますが、別の行に分けて表示すると、固定されていないタブとの区別がより直感的になります。効果は以下の通り:&lt;/p&gt;
&lt;p caption=&#39;tab 固定效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b6868fe5-65b6-4c6b-bd81-3bd15fada494.webp&#39; alt=&#39;tab 固定效果&#39; title=&#39;tab 固定效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;注意点として、デフォルトでは固定されたタブはマウス中ボタンやcmd + wで閉じることができません（押すと固定されていないタブが開かれます）。この動作は変更可能です:&lt;/p&gt;
&lt;p caption=&#39;cmd + w 效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/0259919c-dd23-44f5-89e6-026c2140a424.webp&#39; alt=&#39;cmd + w 效果&#39; title=&#39;cmd + w 效果&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;タブ閉じるボタン&#34;&gt;タブ閉じるボタン&lt;/h3&gt;
&lt;p caption=&#39;隐藏关闭按钮&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/c1e66c49-5cab-4d42-9c04-713a6530bb50.webp&#39; alt=&#39;隐藏关闭按钮&#39; title=&#39;隐藏关闭按钮&#39;&gt;&lt;/p&gt;
&lt;p&gt;左手で cmd + w を使ってタブを閉じることに慣れているため、このオプションは無効にできます。また、実はタブをダブルクリックして閉じる方がより慣れていますが、公式の返答では実装しないとのことです。以下を参照：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Microsoft/vscode/issues/52628#issuecomment-420887497&#34; target=&#34;_blank&#34;&gt; Allow to double click on a tab to close it · Issue #52628 · microsoft/vscode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;タブの折り返し&#34;&gt;タブの折り返し&lt;/h3&gt;
&lt;p caption=&#39;tab wrap&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b72dfdff-c447-457d-89de-8ca3a682281d.webp&#39; alt=&#39;tab wrap&#39; title=&#39;tab wrap&#39;&gt;&lt;/p&gt;
&lt;p&gt;多くのタブを開いている場合、タブをスクロールするのが面倒で全体像を把握しづらくなるため、私はタブの折り返しを好みます。効果は以下の通り：&lt;/p&gt;
&lt;p caption=&#39;wrap 效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3738c007-8e6d-4397-a3fb-0a5210402ed2.webp&#39; alt=&#39;wrap 效果&#39; title=&#39;wrap 效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;少し困る点は、折り返しによって複数行になったタブが、前述の「タブ上部の青色ハイライト」と混同される可能性があることです（青い線が上のタブのものか下のタブのものか、一瞬考えてしまうため直感的ではありません）。タブにより多くの内容を表示するか、直感的に分かりやすくするかは、各自で選択してください：&lt;/p&gt;
&lt;p caption=&#39;高亮修改 + tab 高亮效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/bba12f32-b355-4550-aba5-c59950ed66fc.webp&#39; alt=&#39;高亮修改 + tab 高亮效果&#39; title=&#39;高亮修改 + tab 高亮效果&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;タブの高さ&#34;&gt;タブの高さ&lt;/h3&gt;
&lt;p caption=&#39;紧凑 tab 布局&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3224c016-4adb-41d2-82f8-83391960259d.webp&#39; alt=&#39;紧凑 tab 布局&#39; title=&#39;紧凑 tab 布局&#39;&gt;&lt;/p&gt;
&lt;p&gt;コンパクトなレイアウトは全体像の把握とスペースの節約に役立ちます。&lt;/p&gt;
&lt;h3 id=&#34;タブをダブルクリックで閉じる（？）&#34;&gt;&lt;s&gt;タブをダブルクリックで閉じる（？）&lt;/s&gt;&lt;/h3&gt;
&lt;p caption=&#39;没懂这个设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/3385a990-b192-4aec-963a-ee5996faf19d.webp&#39; alt=&#39;没懂这个设置&#39; title=&#39;没懂这个设置&#39;&gt;&lt;/p&gt;
&lt;p&gt;このオプションは文字通り、公式が実装しないと表明した「タブをダブルクリックで閉じる」機能（前述の通り）のようです。しかし、競合する可能性のある「タブをダブルクリックしてエディターグループを自動拡張」を無効にしても、この設定は機能しません。私の理解が間違っているのか、それともバグなのかは不明です。&lt;/p&gt;
&lt;h3 id=&#34;ネイティブタブ&#34;&gt;ネイティブタブ&lt;/h3&gt;
&lt;p&gt;これに関連する設定は2つあります：&lt;/p&gt;
&lt;p caption=&#39;原生 tab&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/09ad718f-b4c3-40a3-8c92-8e399613540a.webp&#39; alt=&#39;原生 tab&#39; title=&#39;原生 tab&#39;&gt;&lt;/p&gt;
&lt;p&gt;最初の設定を有効にすると、複数のプロジェクトウィンドウを1つのウィンドウに統合できます。「ウィンドウ」オプションに「すべてのウィンドウを統合」が表示され、1つのウィンドウで複数のプロジェクトを切り替えることができ、非常に便利です：&lt;/p&gt;
&lt;p caption=&#39;合并所有窗口&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/8d13f532-cc6a-49a6-9d2c-88aabf5904e3.webp&#39; alt=&#39;合并所有窗口&#39; title=&#39;合并所有窗口&#39;&gt;&lt;/p&gt;
&lt;p&gt;ただし、この場合、カスタムタイトルは使用できません（個人的にはあまり有用ではないと思います）。カスタムタイトルは以下のようになります：&lt;/p&gt;
&lt;p caption=&#39;自定义标题栏效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/1d16fa15-9ee4-4647-8458-1103a659a165.webp&#39; alt=&#39;自定义标题栏效果&#39; title=&#39;自定义标题栏效果&#39;&gt;&lt;/p&gt;
&lt;p&gt;最初の設定を有効にすると、2番目の設定は無効になり、native や custom に設定しても効果がありません。最初の設定を無効にし、2番目の設定を native にすると、「すべてのウィンドウを統合」も「カスタムタイトルバー」も使用できなくなります（この設定の意義がわかりません）。&lt;/p&gt;
&lt;h3 id=&#34;ツリービューのドラッグ＆ドロップ&#34;&gt;ツリービューのドラッグ＆ドロップ&lt;/h3&gt;
&lt;p caption=&#39;最好禁用拖拽文件&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/f4f866b8-c0be-456f-8336-2a229c532f61.webp&#39; alt=&#39;最好禁用拖拽文件&#39; title=&#39;最好禁用拖拽文件&#39;&gt;&lt;/p&gt;
&lt;p&gt;誤って操作してしまうことが多く、数百の変更が発生する可能性があるため、無効にしています。&lt;/p&gt;
&lt;h3 id=&#34;検索結果の自動折りたたみ&#34;&gt;検索結果の自動折りたたみ&lt;/h3&gt;
&lt;p caption=&#39;少于 10 个的文件夹展开&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/5aab9aef-806d-42a0-ab7c-7d58ae4b4849.webp&#39; alt=&#39;少于 10 个的文件夹展开&#39; title=&#39;少于 10 个的文件夹展开&#39;&gt;&lt;/p&gt;
&lt;p&gt;デフォルトでは常に展開されますが、検索結果が多すぎる場合（通常は入力が完了していないため）、展開する必要がなく、全体像の把握を妨げます。&lt;/p&gt;
&lt;p&gt;また、検索バーに「除外ファイル」を追加していない場合、NextJSプロジェクトの.nextディレクトリなど、膨大な検索結果が表示される可能性があるため、この設定も必要です。&lt;/p&gt;
&lt;p&gt;注意点として、この「展開」「折りたたみ」の10ファイル制限は、検索結果全体のフォルダ数ではなく、特定のフォルダ内に表示されるファイル数です：&lt;/p&gt;
&lt;p caption=&#39;多余 10 个的文件夹折叠&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/67c50309-319c-474a-addf-bbd33925d827.webp&#39; alt=&#39;多余 10 个的文件夹折叠&#39; title=&#39;多余 10 个的文件夹折叠&#39;&gt;&lt;/p&gt;
&lt;p&gt;したがって、特定のフォルダ内に検索結果に一致するファイルが多すぎる場合（フォルダが折りたたまれる）、通常はさらに検索情報を提供する必要があるかどうかを確認する必要があります。&lt;/p&gt;
&lt;h3 id=&#34;検索ボックスへの自動入力&#34;&gt;検索ボックスへの自動入力&lt;/h3&gt;
&lt;p caption=&#39;全局搜索自动带入选择内容&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/42995472-6453-4e61-881e-d7e0ae5da443.webp&#39; alt=&#39;全局搜索自动带入选择内容&#39; title=&#39;全局搜索自动带入选择内容&#39;&gt;&lt;/p&gt;
&lt;p&gt;通常、選択した内容を検索したい場合があるため、「Seed On Focus」オプションを使用すると、cmd + v の操作を省略できます。&lt;/p&gt;
&lt;p&gt;ただし、「検索ウィジェット」で選択後にフォーカスを移動した際に自動的に選択内容を入力する機能とは異なります。エディターで内容を選択し、検索ウィジェットにフォーカスを移動する場合、必ずしも検索のためではなく、現在のエディターで選択した同じ内容をハイライトして表示するためだけの場合もあります。しかし、この場合、選択後にフォーカスを移動すると自動的に選択内容が置き換えられ、多くの場合期待通りではありません。&lt;/p&gt;
&lt;p&gt;一方、内容を選択した後に検索ビュー（右側）にフォーカスを移動する場合は、ほぼ確実に検索のためです。&lt;/p&gt;
&lt;p&gt;また、検索結果については、そのドキュメント内での位置を特定するために行番号を知りたいため、行番号を表示することも重要です。&lt;/p&gt;
&lt;p&gt;最後に、Smart Caseは小技です。すべて小文字で入力した場合は、検索名をあまり覚えていないことを意味し、検索内容（キャメルケースの関数名など）の特定の文字が大文字であることを確信している場合は、大文字と小文字を区別して検索します。非常に便利です。&lt;/p&gt;
&lt;p&gt;さらに、前回入力した内容を記憶していて、それが選択状態であれば、自分の入力予想と一致しない場合でも、直接入力すれば問題ありません。以前の検索内容がまだ役立つのであれば、それはさらに良いでしょう。↓&lt;/p&gt;
&lt;p caption=&#39;注意与搜索小组件的差别&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/b84b5d58-94cb-448f-bd1a-cc129aac13bd.webp&#39; alt=&#39;注意与搜索小组件的差别&#39; title=&#39;注意与搜索小组件的差别&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;検索でグローバルなignoreを無視&#34;&gt;検索でグローバルなignoreを無視&lt;/h3&gt;
&lt;p caption=&#39;全局忽略设置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/21a936ed-29c9-4613-b6d4-5ad910fc04f0.webp&#39; alt=&#39;全局忽略设置&#39; title=&#39;全局忽略设置&#39;&gt;&lt;/p&gt;
&lt;p&gt;Gitにはグローバルなデフォルトのignore設定があり、このオプションを有効にすると検索時にリストされたファイルやフォルダを無視できます。通常は有効にしておくのが良いでしょう。&lt;/p&gt;
&lt;p&gt;また、親ディレクトリでignoreを有効にするオプションもあります。意味がよく分かりませんが、多階層のGit管理のためかもしれません。とにかく無視するのであれば、ということで私もチェックを入れました：&lt;/p&gt;
&lt;p caption=&#39;统统勾上&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/fa5ad841-87ee-460f-ad01-d1c7a34f2553.webp&#39; alt=&#39;统统勾上&#39; title=&#39;统统勾上&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;デバッグとテスト&#34;&gt;デバッグとテスト&lt;/h3&gt;
&lt;p&gt;私の技術レベルが限られているため、VSCodeのデバッグとテスト機能はほとんど使っていません。NextJSのようなNodeJSアプリケーションをデバッグする際に使用した程度で、使い方はChromeとほぼ同じです。使用頻度が低いため、特に問題点も見つからず、最適化できる設定もないので、ここでは触れません。&lt;/p&gt;
&lt;h3 id=&#34;ファイル変更の表示効果&#34;&gt;ファイル変更の表示効果&lt;/h3&gt;
&lt;p caption=&#39;实线比「装订线」好看&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/ef52ba2e-5ff7-4f8f-963d-32da4f899fe6.webp&#39; alt=&#39;实线比「装订线」好看&#39; title=&#39;实线比「装订线」好看&#39;&gt;&lt;/p&gt;
&lt;p&gt;行番号表示の列で、差分を実線で表示するか「ガター」で表示するかを設定できます：&lt;/p&gt;
&lt;p caption=&#39;实在不知道装订线存在的意义&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/4c009676-4e9a-4c90-8eab-5ceffae9593d.webp&#39; alt=&#39;实在不知道装订线存在的意义&#39; title=&#39;实在不知道装订线存在的意义&#39;&gt;&lt;/p&gt;
&lt;p&gt;私は実線の方が好みなので、これらのオプションは両方とも無効にしました。&lt;/p&gt;
&lt;h3 id=&#34;gitコミットボタンの無効化&#34;&gt;Gitコミットボタンの無効化&lt;/h3&gt;
&lt;p caption=&#39;移除多余的 UI 按钮&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/6343ab7e-7fc4-4cdc-8b0d-b65eae20b0b7.webp&#39; alt=&#39;移除多余的 UI 按钮&#39; title=&#39;移除多余的 UI 按钮&#39;&gt;&lt;/p&gt;
&lt;p&gt;正直なところ、左側のこのコミットボタンは一度も使ったことがありません。常にコマンドラインでGit操作を行っているので、このオプションは無効にしました。&lt;/p&gt;
&lt;p&gt;同様に、このボタン（GitHub Copilotのボタンのようで、自動的にコミットメッセージを生成するもの）も無効にしました。特に会社のプロジェクトでは、要件/bugカード番号をメッセージに含めることが強制されているため、このようなインテリジェントなコミットメッセージ生成はさらに役に立ちません：&lt;/p&gt;
&lt;p caption=&#39;移除自动写提交信息&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/111f48be-42e0-4f6a-b490-7dc832b15045.webp&#39; alt=&#39;移除自动写提交信息&#39; title=&#39;移除自动写提交信息&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;拡張機能&#34;&gt;拡張機能&lt;/h2&gt;
&lt;h3 id=&#34;通知の無効化&#34;&gt;通知の無効化&lt;/h3&gt;
&lt;p caption=&#39;取消全部扩展通知&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/caa23ff0-089b-4035-90e1-c914e44c61ac.webp&#39; alt=&#39;取消全部扩展通知&#39; title=&#39;取消全部扩展通知&#39;&gt;&lt;/p&gt;
&lt;p&gt;拡張機能から何かを教えてもらう必要はありません。必要があれば、自分から探します。&lt;/p&gt;
&lt;h2 id=&#34;ターミナル&#34;&gt;ターミナル&lt;/h2&gt;
&lt;h3 id=&#34;右クリックの動作&#34;&gt;右クリックの動作&lt;/h3&gt;
&lt;p caption=&#39;终端邮件默认居然是选中+菜单&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/8c75e65f-ae00-49f1-982f-82c682b4a2f9.webp&#39; alt=&#39;终端邮件默认居然是选中+菜单&#39; title=&#39;终端邮件默认居然是选中+菜单&#39;&gt;&lt;/p&gt;
&lt;p&gt;通常、マウスの左クリックで選択した後、右クリックでコンテキストメニューを表示します。しかしVSCodeのデフォルト動作は、内容（単語）を選択すると右クリックで表示されるようになっています。可能ではありますが、必要ありません。&lt;/p&gt;
&lt;h3 id=&#34;ターミナルの最大行数&#34;&gt;ターミナルの最大行数&lt;/h3&gt;
&lt;p caption=&#39;最大记录行&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/67d6cb52-ce20-40d2-ab50-548b7a4aab41.webp&#39; alt=&#39;最大记录行&#39; title=&#39;最大记录行&#39;&gt;&lt;/p&gt;
&lt;p&gt;これは実際には変更しなくても構いません。まれにかなり前のログ情報を見る必要がある場合があり、私の64GBメモリを考慮すると、大きく設定しても問題ありません。&lt;/p&gt;
&lt;h3 id=&#34;ターミナルのスクロールアニメーション&#34;&gt;ターミナルのスクロールアニメーション&lt;/h3&gt;
&lt;p caption=&#39;奇怪的动画，关了&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/7bd7b784-c3e5-456a-9aea-f0374dfa62b0.webp&#39; alt=&#39;奇怪的动画，关了&#39; title=&#39;奇怪的动画，关了&#39;&gt;&lt;/p&gt;
&lt;p&gt;アニメーションは好きですが（エレガントです）、ターミナルのスクロールアニメーションには慣性があるようで、スクロール量を制御しにくく、エディタやワークベンチ内のスクロール効果とは大きく異なるため、無効にしました。&lt;/p&gt;
&lt;h2 id=&#34;css-less-sass&#34;&gt;CSS/Less/Sass&lt;/h2&gt;
&lt;h3 id=&#34;重複プロパティのlint警告&#34;&gt;重複プロパティのlint警告&lt;/h3&gt;
&lt;p caption=&#39;需要设置三次&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/067e3056-d82f-4910-9e47-519259d54577.webp&#39; alt=&#39;需要设置三次&#39; title=&#39;需要设置三次&#39;&gt;&lt;/p&gt;
&lt;p&gt;これは非常に有用です。外部から複数のプロパティ値をコピー＆ペーストする場合（ブラウザの要素検査からstyleをコピーするのが一般的）、重複するプロパティを削除する必要があります。&lt;/p&gt;
&lt;h2 id=&#34;git&#34;&gt;Git&lt;/h2&gt;
&lt;h3 id=&#34;自動stash&#34;&gt;自動Stash&lt;/h3&gt;
&lt;p caption=&#39;少操作一次&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/4fee6e57-9088-4a39-bbfe-c86ea5c9beb2.webp&#39; alt=&#39;少操作一次&#39; title=&#39;少操作一次&#39;&gt;&lt;/p&gt;
&lt;p&gt;図の通り、説明は十分です。有効にすることをお勧めします。操作が1ステップ減ります。&lt;/p&gt;
&lt;h2 id=&#34;サードパーティ拡張機能&#34;&gt;サードパーティ拡張機能&lt;/h2&gt;
&lt;p&gt;特に言うことはありません。拡張機能をインストールするのは、自分のニーズがあるからです。自分の要件に合わせて設定してください。&lt;/p&gt;
&lt;h3 id=&#34;gitlens&#34;&gt;GitLens&lt;/h3&gt;
&lt;p&gt;ただし、一部のプラグインでは有料機能の推薦を無効にできます。そうです、&lt;code&gt;GitLens&lt;/code&gt;のことです。Gitブランチのマージ状況を（偶然）確認する際に、有料機能のプロンプトが表示されることがあります。これは無効にできます（プラグイン開発者の寛大さに感謝します）：&lt;/p&gt;
&lt;p caption=&#39;关掉 GitLens 付费功能提醒&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/28974458-b244-4ed9-919e-affe90c409fe.webp&#39; alt=&#39;关掉 GitLens 付费功能提醒&#39; title=&#39;关掉 GitLens 付费功能提醒&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;one-dark-pro&#34;&gt;One Dark Pro&lt;/h3&gt;
&lt;p caption=&#39;高亮部分代码&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/a1ac82b3-7b1c-4fc4-9327-2cd04796bbee.webp&#39; alt=&#39;高亮部分代码&#39; title=&#39;高亮部分代码&#39;&gt;&lt;/p&gt;
&lt;p&gt;これは私のお気に入りです。メソッドや関数名がより目立つようになります：&lt;/p&gt;
&lt;p caption=&#39;效果&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/make-vscode-great-forever/d6235ab1-a532-4188-be52-2f29908b31e5.webp&#39; alt=&#39;效果&#39; title=&#39;效果&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;あとがき&#34;&gt;あとがき&lt;/h2&gt;
&lt;p&gt;これだけ多くの設定を紹介しましたが、自分に合ったものが最も重要です。皆さんが効率的に作業し、早く帰宅できることを願っています！&lt;/p&gt;
</description>
            <pubDate>Thu, 21 Dec 2023 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/life/make-vscode-great-forever.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/life/make-vscode-great-forever.html</guid>
            
                <category>生活</category>
            
                <category>折腾</category>
            
                <category>教程</category>
            
                <category>技巧</category>
            
                <category>JavaScript</category>
            
                <category>工作流</category>
            
                <category>VSCode</category>
            
                <category>设置</category>
            
            
                <category>life</category>
            
        </item>
        
        <item>
            <title>Apple TVで北京聯通IPTVを視聴する</title>
            <description>&lt;h2 id=&#34;はじめに&#34;&gt;はじめに&lt;/h2&gt;
&lt;p&gt;以前&lt;a href=&#34;/life/the-way-to-watching-tv.html&#34;&gt;このブログ記事&lt;/a&gt;で、家庭での映画鑑賞の方法について紹介しました。その中で触れたポイントの一つは、ネット上で他の人が取得したIPTVの番組アドレス（m3u拡張子）をiPlayTVに入れると直接再生できるというものです。しかし、この番組アドレスは一定期間で無効になってしまいます。これは、中国聯通のIPTVサーバーが定期的に番組の再生アドレスを更新するためで、Apple TVに設定したアドレスは固定されており、リアルタイムで更新できないからです。そこで、この問題を解決する方法を紹介します。&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(253, 235, 236); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;**使用前の必読事項：**私は北京聯通のブロードバンドを利用しており、**光回線終端装置（ONU）をブリッジモードに設定し、ルーターでPPPoE接続を行い、ソフトウェアルーターR4Sをサブルーター**として接続しています。このチュートリアルはこのネットワークトポロジーを前提としています。「光回線終端装置をブリッジモード + R4SをメインルーターとしてPPPoE接続」または「光回線終端装置でPPPoE接続 + R4Sをサブルーター」などの他のネットワーク構成でも実現可能ですが、R4Sの重要な設定がこのチュートリアルと若干異なる場合があります。検索して要点を理解し、完全に同じにする必要はありません。&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(251, 243, 219); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;同様に、光回線終端装置で直接PPPoE接続している場合、光回線終端装置からケーブルを直接サブ/メインルーターに接続してマルチキャストをユニキャストに変換することもできます。また、対応デバイスで直接マルチキャストアドレスを使用して再生することも可能で、私のように面倒な手順は必要ありません。具体的にはご家庭のネットワーク構成によります。&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(251, 236, 221); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;このチュートリアルは北京聯通IPTVでのみテスト済みです。他の地域では差異がある可能性があります。地域に強く依存する内容が記載されている場合は、お住まいの地域に合わせて対応する内容に置き換えてください。&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(244, 238, 238); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;設定を変更する前に、万が一に備えてすべてのルーターやデバイスの設定をバックアップしてください。&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(251, 243, 219); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;私が使用しているソフトウェアルーターはR4Sで、2つのネットワークポートがあります。私と同じネットワークトポロジーの場合、ソフトウェアルーターに少なくとも2つ以上のネットワークポートがあることを確認してください。1つはメインルーターに接続し、もう1つは光回線終端装置に接続する必要があるためです。&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgba(244, 240, 247, 0.8); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;我が家の光回線終端装置のネットワークセグメントは192.168.1.x、メインルーターのネットワークセグメントは192.168.5.xです。光回線終端装置のアドレスは192.168.1.1、R4Sのアドレスは192.168.5.2、メインルーターのLANポートアドレスは192.168.5.1、ルーターのWANポートアドレスは192.168.1.2です。&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&#34;無料利用が可能かどうかを確認&#34;&gt;無料利用が可能かどうかを確認&lt;/h2&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(231, 243, 248); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;現在、北京地域のIPTVには認証が追加されていませんが、私が確認した情報によると、他の地域の一部の通信事業者はIPTVに暗号化認証を導入しています。つまり、通信事業者が提供するIPTVボックスのMACアドレスを使用して接続（ボックスが復号化の役割を果たす）しなければ、ボックスなしでソフトウェアルーターを使用してLAN内の任意のデバイスで再生することはできません。具体的な実現方法は複雑で、このチュートリアルではこのシナリオについては紹介しません。&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&#34;事前にvlcをダウンロード&#34;&gt;事前にVLCをダウンロード&lt;/h3&gt;
&lt;p&gt;光回線終端装置をブリッジモードに設定し、ルーターでPPPoE接続を行うと、光回線終端装置に接続してもインターネットに接続できません。そのため、後でテストを行うために、事前にPCにVLCプレーヤーをダウンロードしておいてください。VLCプレーヤーは以下のリンクからダウンロードできます：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.videolan.org/vlc/&#34; target=&#34;_blank&#34;&gt; Official download of VLC media player, the best Open Source player - VideoLAN&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;光回線終端装置に接続&#34;&gt;光回線終端装置に接続&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;PCを有線で光モデムのIPTVポートに接続&lt;/strong&gt;します（光モデムにIPTVポートが見当たらない場合、それは光モデムが混在接続をサポートしていることを意味し、つまりポートがブロードバンドとIPTVを区別せず、どのポートに接続しても構いません）。その後、VLCソフトウェアで以下の手順を実行します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;File → Open Networkを開きます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下にあるOpen RTP/UDP Streamをクリックします。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ProtocolはRTPを選択し、ModeはMulticastを選択し、IP Addressには&lt;code&gt;239.3.1.241&lt;/code&gt;（または&lt;code&gt;rtp://239.3.1.241&lt;/code&gt;、具体的にどちらかは忘れました）を入力し、ポートには&lt;code&gt;8000&lt;/code&gt;を入力します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Openをクリックした後、北京衛視が見える場合、無料で視聴できることを意味します。&lt;/p&gt;
&lt;p caption=&#39;VLC RTP 播放&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/ea9168ee-6086-42df-b6b4-269900eb5592.webp&#39; alt=&#39;VLC RTP 播放&#39; title=&#39;VLC RTP 播放&#39;&gt;&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(251, 243, 219); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;💡&lt;/span&gt;&lt;span&gt;ここにある `rtp://239.3.1.241:8000` は北京衛星テレビのマルチキャストアドレスです。将来このアドレスは変更される可能性があります。正確なアドレスについては、`https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom.m3u` こちらで任意の rtp パスの後にある IP アドレスをテストできます。&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&#34;基本概念の説明&#34;&gt;基本概念の説明&lt;/h2&gt;
&lt;p&gt;詳細を知りたくない場合は次のセクションに進んでください。&lt;/p&gt;
&lt;h3 id=&#34;iptv&#34;&gt;IPTV&lt;/h3&gt;
&lt;p&gt;ウィキペディアによる IPTV の説明：&lt;/p&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(241, 241, 239); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;📖&lt;/span&gt;&lt;span&gt;インターネットプロトコルテレビ（英語: Internet Protocol Television、略称: IPTV）はブロードバンドテレビの一種です。IPTV はブロードバンドネットワークを媒体としてテレビ情報を伝送するシステムで、放送番組をブロードバンド上のインターネットプロトコル（Internet Protocol, IP）を通じて加入者にデジタルテレビサービスを提供します。ネットワークを使用する必要があるため、IPTV サービスプロバイダーは通常、インターネット接続や IP 電話などの関連サービスもセットで提供し、「トリプルプレイ」サービスとも呼ばれます。IPTV はデジタルテレビの一種であるため、通常のテレビには対応するセットトップボックスが必要で、プロバイダーは通常、ビデオオンデマンドサービスも同時に提供します。ブロードバンドネットワークとインターネットプロトコルを介していますが、IPTV は必ずしもインターネットを経由するわけではなく、伝送品質を確保するためにローカルエリアネットワークで伝送されることがあります。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;これにより、一般的に IPTV はブロードバンドプロバイダーが提供するサービスであり、これを通じてテレビを見ることができます。&lt;/p&gt;
&lt;h3 id=&#34;マルチキャスト&#34;&gt;マルチキャスト&lt;/h3&gt;
&lt;p&gt;IPTV を実現する技術的手段の一つで、英語では「multicast」と呼ばれ、日本語では「マルチキャスト」とも訳されます。具体的な概念を完全に理解する必要はありませんが、ユニキャストと比較して以下の特徴があります：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;インターネット帯域を占有しません。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IPTV ボックスは認証の役割を果たし、IPTV 事業者はグループに対してブロードキャストするため、自社サーバーへの負荷が比較的小さくなります。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;欠点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;光モデムの IPTV ポートに有線接続する必要があります（一部の光モデムは混在接続をサポートしており、IPTV ポートとブロードバンドポートを区別しません）。そのため、IPTV ボックスに接続されたデバイスしか使用できず、WiFi を利用して家庭内の任意のデバイスでネットワークテレビを見ることはできません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ユニキャスト&#34;&gt;ユニキャスト&lt;/h3&gt;
&lt;p&gt;もう一つの古い IPTV 実装技術で、初期の IPTV ユーザーが少ない時期に使用されていました。マルチキャストと比較すると、その欠点が利点となり、逆もまた同様です：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;接続後、ローカルエリアネットワークで WiFi をサポートし、任意のデバイスで再生できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;欠点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;サーバーと1対1で接続するため、サーバーへの負荷が大きく、ユーザーが多いと再生が遅くなる可能性があります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ブロードバンドの帯域幅を占有し、インターネット接続を直接使用して再生します（現在のライブストリーミングと同様です）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;udpxy&#34;&gt;udpxy&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; udpxy サーバーは**UDP ストリームを HTTP ストリームに変換するプロキシサーバー**で、IP ライブストリームを HTTP ストリームに変換し、さまざまな端末での再生を容易にします。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;マルチキャストアドレスを直接取得できない場合、マルチキャストアドレスをユニキャストアドレスに変換するために使用されます。例えば、マルチキャストアドレスが a:b と d:e（a、d は IP アドレス、b、e はポート）の場合、ユニキャストアドレスに変換すると、統一されたアドレス z/a/b、z/d/e になります。プレーヤーはこのアドレス z を監視するだけで済みます。&lt;/p&gt;
&lt;h3 id=&#34;m3u&#34;&gt;m3u&lt;/h3&gt;
&lt;blockquote style=&#39;border-color: ;color: &#39;&gt;&lt;p&gt; **M3U**（MP3 URL の略称）は、マルチメディアリストを再生するためのファイル形式で、当初は MP3 などのオーディオファイルを再生するために設計されましたが、現在では多くのソフトウェアがビデオファイルリストの再生形式として使用しています。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;m3u ファイルは、すべてのマルチキャストアドレスを含むテキストファイルです。Apple TV やコンピュータでこのファイルのアドレスを読み取ると、その中のビデオアドレスを再生できます。&lt;/p&gt;
&lt;h3 id=&#34;epg&#34;&gt;EPG&lt;/h3&gt;
&lt;p&gt;番組表情報を含みます。前の手順で m3u アドレスを取得した後、その中には個々の IP アドレスが含まれていますが、各 IP アドレスがどのチャンネルに対応するかを知るにはどうすればよいでしょうか？この時、EPG を使用してペアリングする必要があります。EPG には各アドレスの番組情報や、チャンネルの簡単な説明さえ含まれています。EPG は通常、ビデオ信号と一緒に放送されます。&lt;/p&gt;
&lt;h2 id=&#34;ネットワークトポロジー&#34;&gt;ネットワークトポロジー&lt;/h2&gt;
&lt;p caption=&#39;网络拓扑-主路由拨号&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/0349a1d5-caeb-4233-b36b-8bc1c7db7565.webp&#39; alt=&#39;网络拓扑-主路由拨号&#39; title=&#39;网络拓扑-主路由拨号&#39;&gt;&lt;/p&gt;
&lt;h2 id=&#34;実践操作&#34;&gt;実践操作&lt;/h2&gt;
&lt;p class=&#39;content-callout&#39; style=&#39;background: rgb(251, 243, 219); color: ;&#39;&gt;&lt;span class=&#39;content-callout-icon&#39;&gt;🚧&lt;/span&gt;&lt;span&gt;始める前に、前述の内容を確認して無料で利用できるかどうかをチェックしてください。&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&#34;ソフトウェアルーターの設定&#34;&gt;ソフトウェアルーターの設定&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;udpxy と luci-udpxy のインストール&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;この手順は通常の操作です。UIからのインストールが最も簡単です（インストール完了後、有効化する前に最後のステップまで進めてください）。&lt;/p&gt;
&lt;p caption=&#39;软件安装界面&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/2be1ca35-90a8-4936-89cd-5458557ac064.webp&#39; alt=&#39;软件安装界面&#39; title=&#39;软件安装界面&#39;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新しいネットワークインターフェースの作成/設定&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;この手順は、ソフトウェアルーターが光モデムからのデータを認識できるようにするためのものです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ネットワーク-インターフェース&lt;/code&gt; で新しいインターフェースを作成し、任意の名前（例: &lt;code&gt;IPTV&lt;/code&gt;）を付けます：&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;新建 IPTV 接口&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/a938e2a7-9723-40f5-8b86-3ed151ba12c5.webp&#39; alt=&#39;新建 IPTV 接口&#39; title=&#39;新建 IPTV 接口&#39;&gt;&lt;/p&gt;
&lt;p&gt;矢印部分に注意してください。私はすでに新規作成したため、括弧内に「IPTV」という文字が表示されていますが、新規作成した直後は表示されていません。ここで、eth1は私のLANポートで、メインルーターに接続されています。eth0は別のインターフェースで、光回線終端装置（IPTVポート）に接続されています。ここで私は以前に設定を変更しました。デフォルトでは、eth0がLANポート、eth1がWANポートですが、これは重要ではありません。このステップでは、WANポートをIPTVポートとして使用します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「IPTV」インターフェースのゲートウェイホップ数とファイアウォール設定を構成する：&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;配置网关跃点&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/d1df1f84-7240-4eb9-872b-6871f9c895a6.webp&#39; alt=&#39;配置网关跃点&#39; title=&#39;配置网关跃点&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;防火墙配置到 wan 上&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/c0e4032b-f066-4fcf-b906-dae85a37d070.webp&#39; alt=&#39;防火墙配置到 wan 上&#39; title=&#39;防火墙配置到 wan 上&#39;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WANポートのゲートウェイホップ数を設定：&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;Wan 口网关跃点&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/21347824-ca57-4715-9fe9-cd7b6be0f282.webp&#39; alt=&#39;Wan 口网关跃点&#39; title=&#39;Wan 口网关跃点&#39;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LANポートのIGMPスニッフィング設定：&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;IGMP 嗅探&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/b075aaec-042b-4f9d-9437-27ea4d17211e.webp&#39; alt=&#39;IGMP 嗅探&#39; title=&#39;IGMP 嗅探&#39;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ネットワークファイアウォールの設定&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;网络防火墙配置&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/577418eb-c3f6-43be-b73b-b1cf3ab5dcea.webp&#39; alt=&#39;网络防火墙配置&#39; title=&#39;网络防火墙配置&#39;&gt;&lt;/p&gt;
&lt;p caption=&#39;防火墙配置2&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/b3ce719b-a05d-41ef-ab4a-12eb866178a8.webp&#39; alt=&#39;防火墙配置2&#39; title=&#39;防火墙配置2&#39;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;udpxyサービスの設定&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;図のように設定してください。ここで注意すべきは、eth0がWANポートであることです。間違えないようにしてください：&lt;/li&gt;
&lt;/ul&gt;
&lt;p caption=&#39;打开 UDPXY&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/bcd40c05-ed7f-43fd-b833-4cee94948150.webp&#39; alt=&#39;打开 UDPXY&#39; title=&#39;打开 UDPXY&#39;&gt;&lt;/p&gt;
&lt;p&gt;最後に [&lt;a href=&#34;http://192.168.5.2:4022/status&#34;&gt;http://192.168.5.2:4022/status&lt;/a&gt;]([object Object]) を開いて、udpxy サービスが正常に起動しているかどうかを確認します：&lt;/p&gt;
&lt;p caption=&#39;看到这个就表示成功了&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/189e9cb4-80c9-4b5d-8f57-722660e66145.webp&#39; alt=&#39;看到这个就表示成功了&#39; title=&#39;看到这个就表示成功了&#39;&gt;&lt;/p&gt;
&lt;p&gt;その後、以前にVLCで開いていたアドレス &lt;code&gt;rtp://239.3.1.241:8000&lt;/code&gt; を `&lt;a href=&#34;http://192.168.2.1:4022/rtp/239.3.1.241:8000%60%60&#34;&gt;http://192.168.2.1:4022/rtp/239.3.1.241:8000``&lt;/a&gt; に変更して再度開いてみてください（下にある「Open RTP/UDP Stream」をクリックせず、直接URLで開きます）。&lt;/p&gt;
&lt;p caption=&#39;尝试将 RTP 变 HTTP 播放&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/582e015c-4260-4181-a81c-5eafc97a1132.webp&#39; alt=&#39;尝试将 RTP 变 HTTP 播放&#39; title=&#39;尝试将 RTP 变 HTTP 播放&#39;&gt;&lt;/p&gt;
&lt;p&gt;その後、ダブルクリックで再生できます：&lt;/p&gt;
&lt;p caption=&#39;成功画面↑&#39;&gt;&lt;img src=&#39;https://static.xheldon.cn/img/in-post/2023/iptv-for-apple-tv-in-beijing/215aa895-e673-419a-a4fc-b94603af8baa.webp&#39; alt=&#39;成功画面↑&#39; title=&#39;成功画面↑&#39;&gt;&lt;/p&gt;
&lt;h3 id=&#34;再生ソフトウェアの使用&#34;&gt;再生ソフトウェアの使用&lt;/h3&gt;
&lt;p&gt;私はApple TV 4Kでテレビを見ています。いくつかの再生ソフトウェアを試したので、簡単に説明します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;iPlayTVは再生できませんでした。理由はわかりません。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fileballではチャンネルの上下移動は問題ありませんが、チャンネルを選択するとすぐにクラッシュします。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最終的にIIVAと同じ開発者のアプリ「TV+」を選択しました。香港ストアでの価格は38香港ドルでした（購入翌日に無料提供が開始され、少し残念でした）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;アドレスの自動更新を実現する方法&#34;&gt;アドレスの自動更新を実現する方法&lt;/h2&gt;
&lt;p&gt;中国聯通のIPTV番組再生アドレスは、定期的に変更されます。ポートが変わることもあれば、IPアドレスが変わることもあります。この方法で再生できなくなった場合、どうすればよいでしょうか？&lt;/p&gt;
&lt;p&gt;ネット上には親切な人がいて、次のような複雑な監視操作を行っています：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.friskit.me/2020/05/31/bjunicom-network.html&#34; target=&#34;_blank&#34;&gt; 光纤入户光猫改桥接+内网转发IPTV=任意设备看电视直播 - Botian&#39;s Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IPTVテレビボックスと聯通サーバー間の通信データを取得し、そのアドレスを入手しました。したがって、次のように直接使用できます：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/qwerttvv/Beijing-IPTV/blob/master/README.md&#34; target=&#34;_blank&#34;&gt; github.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;しかし、ここで重要なポイントは、自宅のソフトウェアルーターのアドレスがこの親切な方のアドレス（192.168.123.1）と同じである必要があり、udpxyのポートを23234に変更することです。そうすれば、このアドレスを直接TV+に設定できます：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom.m3u&#34; target=&#34;_blank&#34;&gt; raw.githubusercontent.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そうでなければ、このファイルの変更を自ら監視し、更新する必要があります。&lt;/p&gt;
&lt;p&gt;ここでは、VercelにAPIサービスを10分でデプロイし、同時にVercelのCorn Jobsサービスを有効化しました。これにより、定期的に関数を実行して変更を検出できます。以下がコードです。あなたも自分でデプロイすることができます：&lt;/p&gt;
&lt;figure class=&#34;highlight javascript&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;50&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;51&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;52&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;53&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;54&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;55&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;56&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;57&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;58&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;59&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;60&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;61&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;62&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;63&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;64&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;65&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;66&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;67&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;68&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;69&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;70&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;71&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;72&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;73&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;74&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;75&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;76&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;77&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;78&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;79&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;80&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;81&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;82&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;83&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;84&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;85&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;86&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;87&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;88&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;89&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;90&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;91&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;92&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;93&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;94&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;95&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;96&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;97&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;98&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;99&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;100&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;101&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;102&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;103&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;104&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;105&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;106&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;107&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;108&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs javascript&#34;&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;import&lt;/span&gt; type &amp;#123; &lt;span class=&#34;hljs-title class_&#34;&gt;NextApiRequest&lt;/span&gt;, &lt;span class=&#34;hljs-title class_&#34;&gt;NextApiResponse&lt;/span&gt; &amp;#125; &lt;span class=&#34;hljs-keyword&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;next&amp;#x27;&lt;/span&gt;;&lt;br&gt;&lt;br&gt;type &lt;span class=&#34;hljs-title class_&#34;&gt;ResponseData&lt;/span&gt; = &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: string,&lt;br&gt;&amp;#125;;&lt;br&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt;/**&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; * 该函数用来将网友通过 IPTV 盒子抓包获取的联通单播地址，转成自己的单播地址&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; * 该函数每天 3 点触发一次，定时检测网友的单播地址是否有更新，使用 vercel corn 任务进行&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; * &lt;span class=&#34;hljs-doctag&#34;&gt;TODO:&lt;/span&gt; 该函数未做鉴权，任何人都可以手动触发检测，为了防止滥用可以加上鉴权，但是 corn 似乎没这个功能&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-comment&#34;&gt; */&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-keyword&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;default&lt;/span&gt; &lt;span class=&#34;hljs-keyword&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;handler&lt;/span&gt;(&lt;span class=&#34;hljs-params&#34;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-params&#34;&gt;  request: NextApiRequest,&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-params&#34;&gt;  response: NextApiResponse&amp;lt;ResponseData&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-params&#34;&gt;&lt;/span&gt;) &amp;#123;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// Note: 步骤&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 1. 获取网友通过监听盒子数据包抓取的（自己搞比较费劲，直接用现成的了）联通 IPTV 永久地址（rtp 协议的组播地址，多用户通用），获取其内容&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 2. 添加本地 udpxy 转发地址&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 3. 获取之前的 github gist 内容以对比二者&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 4. 有差异，则更新 github gist 内容&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// 5. 没有，则不做操作&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-comment&#34;&gt;// Note: 环境变量，自己在 Vercel 中设置好&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; token = process.&lt;span class=&#34;hljs-property&#34;&gt;env&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;GITHUB_TOKEN&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; gist = process.&lt;span class=&#34;hljs-property&#34;&gt;env&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;GIST_URL&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; id = process.&lt;span class=&#34;hljs-property&#34;&gt;env&lt;/span&gt;.&lt;span class=&#34;hljs-property&#34;&gt;GIST_ID&lt;/span&gt;;&lt;br&gt;  &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;fetch&lt;/span&gt;(&lt;br&gt;    &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;https://raw.githubusercontent.com/qwerttvv/Beijing-IPTV/master/IPTV-Unicom.m3u&amp;#x27;&lt;/span&gt;&lt;br&gt;  )&lt;br&gt;    .&lt;span class=&#34;hljs-title function_&#34;&gt;then&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;async&lt;/span&gt; (res) =&amp;gt; &amp;#123;&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (!res.&lt;span class=&#34;hljs-property&#34;&gt;ok&lt;/span&gt;) &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;获取源地址异常&amp;#x27;&lt;/span&gt;);&lt;br&gt;        &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;          &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;获取源地址异常&amp;#x27;&lt;/span&gt;,&lt;br&gt;        &amp;#125;);&lt;br&gt;      &amp;#125;&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; src = &lt;span class=&#34;hljs-keyword&#34;&gt;await&lt;/span&gt; res.&lt;span class=&#34;hljs-title function_&#34;&gt;text&lt;/span&gt;();&lt;br&gt;      &lt;span class=&#34;hljs-comment&#34;&gt;// Note: 替换网友的本地单播地址为我的，其实你也可以将自己家的路由器网段设置成跟网友的一样（192.168.123.x），udpxy 端口转发设置成跟网友一样（23234），你就可以直接使用该地址了&lt;/span&gt;&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; newGist = src.&lt;span class=&#34;hljs-title function_&#34;&gt;replace&lt;/span&gt;(&lt;br&gt;        &lt;span class=&#34;hljs-regexp&#34;&gt;/http\:\/\/192\.168\.123\.1\:23234/g&lt;/span&gt;,&lt;br&gt;        &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;http://192.168.5.2:4022&amp;#x27;&lt;/span&gt;&lt;br&gt;      );&lt;br&gt;      response.&lt;span class=&#34;hljs-title function_&#34;&gt;setHeader&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Content-Type&amp;#x27;&lt;/span&gt;, &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;text/html; charset=utf-8&amp;#x27;&lt;/span&gt;);&lt;br&gt;      &lt;span class=&#34;hljs-comment&#34;&gt;// Note: 获取 gist 的 raw 内容，需要加个 cache-bust 否则每次请求会被缓存&lt;/span&gt;&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;fetch&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;`&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;gist&amp;#125;&lt;/span&gt;?cache-bust=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.floor(&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.random() * &lt;span class=&#34;hljs-number&#34;&gt;100000&lt;/span&gt;)&amp;#125;&lt;/span&gt;`&lt;/span&gt;, &amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-attr&#34;&gt;headers&lt;/span&gt;: &amp;#123;&lt;br&gt;          &lt;span class=&#34;hljs-title class_&#34;&gt;Authorization&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`Bearer &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;token&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;        &amp;#125;,&lt;br&gt;      &amp;#125;)&lt;br&gt;        .&lt;span class=&#34;hljs-title function_&#34;&gt;then&lt;/span&gt;(&lt;span class=&#34;hljs-keyword&#34;&gt;async&lt;/span&gt; (pre) =&amp;gt; &amp;#123;&lt;br&gt;          &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; preGist = &lt;span class=&#34;hljs-keyword&#34;&gt;await&lt;/span&gt; pre.&lt;span class=&#34;hljs-title function_&#34;&gt;text&lt;/span&gt;();&lt;br&gt;          &lt;span class=&#34;hljs-comment&#34;&gt;// console.log(&amp;#x27;preGist:&amp;#x27;, preGist);&lt;/span&gt;&lt;br&gt;          &lt;span class=&#34;hljs-keyword&#34;&gt;if&lt;/span&gt; (&lt;span class=&#34;hljs-title class_&#34;&gt;JSON&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;stringify&lt;/span&gt;(newGist) !== &lt;span class=&#34;hljs-title class_&#34;&gt;JSON&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;stringify&lt;/span&gt;(preGist)) &amp;#123;&lt;br&gt;            &lt;span class=&#34;hljs-comment&#34;&gt;// Note: 更新 Gist&lt;/span&gt;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;const&lt;/span&gt; files = &amp;#123;&lt;br&gt;              &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;IPTV.m3u&amp;#x27;&lt;/span&gt;: &amp;#123;&lt;br&gt;                &lt;span class=&#34;hljs-attr&#34;&gt;content&lt;/span&gt;: newGist,&lt;br&gt;              &amp;#125;,&lt;br&gt;            &amp;#125;;&lt;br&gt;            &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;hljs-title function_&#34;&gt;fetch&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;`https://api.github.com/gists/&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;id&amp;#125;&lt;/span&gt;`&lt;/span&gt;, &amp;#123;&lt;br&gt;              &lt;span class=&#34;hljs-attr&#34;&gt;method&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;PATCH&amp;#x27;&lt;/span&gt;,&lt;br&gt;              &lt;span class=&#34;hljs-attr&#34;&gt;headers&lt;/span&gt;: &amp;#123;&lt;br&gt;                &lt;span class=&#34;hljs-title class_&#34;&gt;Authorization&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`Bearer &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;token&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;                &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;Content-Type&amp;#x27;&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;&amp;#x27;text/plain&amp;#x27;&lt;/span&gt;,&lt;br&gt;              &amp;#125;,&lt;br&gt;              &lt;span class=&#34;hljs-attr&#34;&gt;body&lt;/span&gt;: &lt;span class=&#34;hljs-title class_&#34;&gt;JSON&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;stringify&lt;/span&gt;(&amp;#123; files &amp;#125;),&lt;br&gt;            &amp;#125;)&lt;br&gt;              .&lt;span class=&#34;hljs-title function_&#34;&gt;then&lt;/span&gt;(&lt;span class=&#34;hljs-function&#34;&gt;(&lt;span class=&#34;hljs-params&#34;&gt;s&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &amp;#123;&lt;br&gt;                &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;br&gt;                  &lt;span class=&#34;hljs-string&#34;&gt;`更新成功: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;gist&amp;#125;&lt;/span&gt;?cache-bust=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.floor(&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;                    &lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.random() * &lt;span class=&#34;hljs-number&#34;&gt;1000000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;                  )&amp;#125;&lt;/span&gt;`&lt;/span&gt;&lt;br&gt;                );&lt;br&gt;                &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;                  &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`更新成功: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;gist&amp;#125;&lt;/span&gt;?cache-bust=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.floor(&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;                    &lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.random() * &lt;span class=&#34;hljs-number&#34;&gt;1000000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;                  )&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;                &amp;#125;);&lt;br&gt;              &amp;#125;)&lt;br&gt;              .&lt;span class=&#34;hljs-title function_&#34;&gt;catch&lt;/span&gt;(&lt;span class=&#34;hljs-function&#34;&gt;(&lt;span class=&#34;hljs-params&#34;&gt;e&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &amp;#123;&lt;br&gt;                &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;`更新失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;);&lt;br&gt;                &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;                  &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`更新失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;                &amp;#125;);&lt;br&gt;              &amp;#125;);&lt;br&gt;          &amp;#125;&lt;br&gt;          &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;br&gt;            &lt;span class=&#34;hljs-string&#34;&gt;`未变化: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;gist&amp;#125;&lt;/span&gt;?cache-bust=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.floor(&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.random() * &lt;span class=&#34;hljs-number&#34;&gt;1000000&lt;/span&gt;)&amp;#125;&lt;/span&gt;`&lt;/span&gt;&lt;br&gt;          );&lt;br&gt;          &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;            &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`未变化: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;gist&amp;#125;&lt;/span&gt;?cache-bust=&lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;&lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.floor(&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;              &lt;span class=&#34;hljs-built_in&#34;&gt;Math&lt;/span&gt;.random() * &lt;span class=&#34;hljs-number&#34;&gt;1000000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-subst&#34;&gt;&lt;span class=&#34;hljs-string&#34;&gt;            )&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;          &amp;#125;);&lt;br&gt;        &amp;#125;)&lt;br&gt;        .&lt;span class=&#34;hljs-title function_&#34;&gt;catch&lt;/span&gt;(&lt;span class=&#34;hljs-function&#34;&gt;(&lt;span class=&#34;hljs-params&#34;&gt;e&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &amp;#123;&lt;br&gt;          &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;`获取自己的 gist 失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;);&lt;br&gt;          &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;            &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`获取自己的 gist 失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;          &amp;#125;);&lt;br&gt;        &amp;#125;);&lt;br&gt;    &amp;#125;)&lt;br&gt;    .&lt;span class=&#34;hljs-title function_&#34;&gt;catch&lt;/span&gt;(&lt;span class=&#34;hljs-function&#34;&gt;(&lt;span class=&#34;hljs-params&#34;&gt;e&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &amp;#123;&lt;br&gt;      &lt;span class=&#34;hljs-variable language_&#34;&gt;console&lt;/span&gt;.&lt;span class=&#34;hljs-title function_&#34;&gt;log&lt;/span&gt;(&lt;span class=&#34;hljs-string&#34;&gt;`获取别人的源失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;);&lt;br&gt;      &lt;span class=&#34;hljs-keyword&#34;&gt;return&lt;/span&gt; response.&lt;span class=&#34;hljs-title function_&#34;&gt;status&lt;/span&gt;(&lt;span class=&#34;hljs-number&#34;&gt;200&lt;/span&gt;).&lt;span class=&#34;hljs-title function_&#34;&gt;json&lt;/span&gt;(&amp;#123;&lt;br&gt;        &lt;span class=&#34;hljs-attr&#34;&gt;msg&lt;/span&gt;: &lt;span class=&#34;hljs-string&#34;&gt;`获取别人的源失败: &lt;span class=&#34;hljs-subst&#34;&gt;$&amp;#123;e&amp;#125;&lt;/span&gt;`&lt;/span&gt;,&lt;br&gt;      &amp;#125;);&lt;br&gt;    &amp;#125;);&lt;br&gt;&amp;#125;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Corn Jobs サービス設定：&lt;/p&gt;
&lt;figure class=&#34;highlight json&#34;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&#34;gutter&#34;&gt;&lt;pre&gt;&lt;span class=&#34;line&#34;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;line&#34;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;pre&gt;&lt;code class=&#34;hljs json&#34;&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;crons&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-punctuation&#34;&gt;[&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;      &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;path&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;/api/get&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;,&lt;/span&gt;&lt;br&gt;      &lt;span class=&#34;hljs-attr&#34;&gt;&amp;quot;schedule&amp;quot;&lt;/span&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;hljs-string&#34;&gt;&amp;quot;0 15 * * *&amp;quot;&lt;/span&gt;&lt;br&gt;    &lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;  &lt;span class=&#34;hljs-punctuation&#34;&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&#34;hljs-punctuation&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;このファイルをプルした後に更新がある場合、gistファイルは自動的に更新されます：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gist.githubusercontent.com/Xheldon/73bf97cb5ac5db2f5237264556b20951/raw/ea44694028a38baefff04ea46c02795e448d76f0/IPTV.m3u&#34; target=&#34;_blank&#34;&gt; gist.githubusercontent.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このように、TV+ にこの gist アドレスをハードコードしておけば、ネットユーザーがこのアドレスを更新したときに自動的に更新されるようになります。&lt;/p&gt;
&lt;h2 id=&#34;参考リンク&#34;&gt;参考リンク&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.lishun.me/iptvhelper-guide&#34; target=&#34;_blank&#34;&gt; 单线融合IPTV到家庭局域网最简单的方法：路由+桥接混合模式&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.friskit.me/2020/05/31/bjunicom-network.html&#34; target=&#34;_blank&#34;&gt; 光纤入户光猫改桥接+内网转发IPTV=任意设备看电视直播 - Botian&#39;s Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.haoyizebo.com/posts/6a0c2301/&#34; target=&#34;_blank&#34;&gt; 北京联通白嫖 IPTV&lt;/a&gt;&lt;/p&gt;</description>
            <pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate>
            <link>https://www.xheldon.com/ja/life/iptv-for-apple-tv-in-beijing.html</link>
            <guid isPermaLink="true">https://www.xheldon.com/ja/life/iptv-for-apple-tv-in-beijing.html</guid>
            
                <category>生活</category>
            
                <category>Apple</category>
            
                <category>折腾</category>
            
                <category>经验</category>
            
                <category>苹果</category>
            
                <category>网络</category>
            
                <category>路由器</category>
            
                <category>教程</category>
            
            
                <category>life</category>
            
        </item>
        
    </channel>
    </rss>