MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
JavaScriptの基礎 - JSONのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
JavaScriptの基礎 - JSON
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == JSON (JavaScript Object Notation) は、JavaScriptのオブジェクトリテラル構文を基にした軽量なテキスト形式のデータ交換フォーマットである。<br> 言語非依存の仕様として設計されており、JavaScriptに限らず多くのプログラミング言語でデータの送受信に広く使用されている。<br> <br> JavaScriptでJSONを操作するための組み込みオブジェクト <code>JSON</code> は、2つのメソッドを提供する。<br> * <code>JSON.parse</code> *: JSON文字列をJavaScriptの値 (オブジェクト、配列、プリミティブ) に変換する。 * <code>JSON.stringify</code> *: JavaScriptの値をJSON文字列に変換 (シリアライズ) する。 <br> <u>シリアライズ時には、JavaScriptの全ての型がJSONとして表現できるわけではないことに注意が必要である。</u><br> <br> <code>undefined</code>、関数、<code>Symbol</code> はオブジェクトプロパティから削除され、<code>NaN</code> や <code>Infinity</code> は <code>null</code> に変換される。<br> また、<code>Date</code> オブジェクトはISO 8601形式の文字列に変換されるが、<code>JSON.parse</code> では自動的に <code>Date</code> に戻されない。<br> <br> JSONを利用したディープコピー (<code>JSON.parse(JSON.stringify())</code>) は手軽な手法であるが、上記の型の制約がある。<br> 現代のWebブラウザやNode.js環境では、<code>Date</code>、<code>Map</code>、<code>Set</code>、循環参照を正しく処理できる <code>structuredClone()</code> が利用できる。<br> <br> Tauri v2では、<code>invoke()</code> によるIPC通信でフロントエンドとRustバックエンド間のデータがJSONを介して自動的にシリアライズ・デシリアライズされる。<br> Rust側では <code>serde</code> クレートにより、構造体のフィールド名変換 (snake_case / camelCase) も自動化される。<br> <br><br> == JSONの基本 == ==== JSONの構文規則 ==== JSONは厳格な構文規則を持つテキストフォーマットである。<br> <u>JavaScriptのオブジェクトリテラルとは異なる点があるため、注意が必要である。</u><br> <br> 主な構文規則を以下に示す。<br> <br> <center> {| class="wikitable" |+ JSONの主な構文規則 ! 規則 !! 説明 |- | キー名は必ず二重引用符 (") で囲む | * 単一引用符 (') は使用不可 * <code>{ "name": "Alice" }</code> は有効<br><code>{ name: "Alice" }</code> は無効 |- | 文字列値は二重引用符で囲む || <code>"hello"</code> は有効<br><code>'hello'</code> は無効 |- | 末尾カンマは使用不可 || 配列やオブジェクトの最後の要素の後にカンマがあると <code>SyntaxError</code> が発生する。 |- | コメントは使用不可 || JavaScript のような <code>// コメント</code> や <code>/* コメント */</code> は無効 |- | 数値は整数または浮動小数点数のみ || <code>Infinity</code> および <code>NaN</code> はJSONとして不正な値である。 |} </center> <br> 有効なJSONの例を以下に示す。<br> <br> <syntaxhighlight lang="json"> { "name": "Alice", "age": 30, "isActive": true, "address": null, "scores": [85, 92, 78], "profile": { "city": "Tokyo", "country": "Japan" } } </syntaxhighlight> <br> ==== JSONの型 と JavaScript型の対応 ==== JSONが扱える型は6種類であり、JavaScriptの全ての型とは対応していない。<br> <br> <center> {| class="wikitable" |+ JSONの型とJavaScript型の対応 ! JSON型 !! JavaScript型 !! 備考 |- | string || string || 1対1対応 |- | number || number || 1対1対応 |- | boolean || boolean || 1対1対応 |- | null || null || 1対1対応 |- | object || object (プレーンオブジェクト) || 1対1対応 |- | array || Array || 1対1対応 |- | (非対応) || undefined || シリアライズ時にプロパティ削除または配列要素がnullに変換 |- | (非対応) || Date || ISO 8601文字列に変換<br>逆変換は行われない。 |- | (非対応) || Function || シリアライズ時にプロパティ削除または配列要素がnullに変換 |- | (非対応) || Map / Set || {} (空オブジェクト) または [] (空配列) に変換 |- | (非対応) || RegExp || {} (空オブジェクト) に変換 |- | (非対応) || BigInt || <u>TypeError</u> が発生する。 |} </center> <br><br> == JSON.parse == ==== 基本的な使用方法 ==== <code>JSON.parse(text)</code> は、JSON文字列をJavaScriptの値に変換するメソッドである。<br> 引数に渡した文字列が有効なJSONでない場合は <code>SyntaxError</code> をスローする。<br> <br> 基本的な使用例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> // JSON文字列をオブジェクトに変換する const obj = JSON.parse('{"name":"Alice","age":30}'); console.log(obj.name); // "Alice" console.log(obj.age); // 30 // 配列のJSONを変換する const arr = JSON.parse('[1, 2, 3]'); console.log(arr); // [1, 2, 3] // プリミティブ値のJSONを変換する const num = JSON.parse('42'); console.log(num); // 42 const str = JSON.parse('"hello"'); console.log(str); // "hello" </syntaxhighlight> <br> ==== reviver関数 ==== <code>JSON.parse(text, reviver)</code> の第2引数にreviver関数を指定することにより、各プロパティの値を変換しながらパースできる。<br> <br> 下表に、reviver関数の仕様を示す。<br> <br> <center> {| class="wikitable" |+ reviver関数の仕様 ! 項目 !! 説明 |- | シグネチャ || <code>function reviver(key, value)</code> の形式で定義する。<br><u>key</u> はプロパティ名 (文字列)、<u>value</u> は変換前の値である。 |- | 処理順序 || 深さ優先探索で葉から根へ処理される。 |- | <u>undefined</u> を返した場合 || そのプロパティは削除される。 |- | ルートオブジェクトの処理 || 空文字列 (<u>""</u>) をキーとして最後に処理される。 |} </center> <br> reviver関数の主な活用例として、JSON文字列として保存されたDateオブジェクトの復元がある。<br> <br> <syntaxhighlight lang="javascript"> const jsonString = '{"name":"Alice","createdAt":"2024-01-15T10:30:00.000Z"}'; const data = JSON.parse(jsonString, (key, value) => { // ISO 8601形式の文字列をDateオブジェクトに変換する if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) { return new Date(value); } return value; }); console.log(data.name); // "Alice" console.log(data.createdAt); // Dateオブジェクト console.log(data.createdAt instanceof Date); // true </syntaxhighlight> <br> プロパティを削除するreviver関数の例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const json = '{"name":"Alice","password":"secret","age":30}'; const filtered = JSON.parse(json, (key, value) => { // パスワードプロパティを除去する if (key === 'password') return undefined; return value; }); console.log(filtered); // { name: "Alice", age: 30 } </syntaxhighlight> <br> ==== エラーハンドリング ==== <code>JSON.parse</code> は無効なJSON文字列が渡された場合に <u>SyntaxError</u> をスローする。<br> そのため、外部から取得したJSON文字列をパースする際は <code>try / catch</code> で処理することが推奨される。<br> <br> <syntaxhighlight lang="javascript"> function safeParseJSON(text) { try { return { success: true, data: JSON.parse(text) }; } catch (error) { if (error instanceof SyntaxError) { console.error('無効なJSON文字列:', error.message); } return { success: false, data: null }; } } // 有効なJSONの場合 const result1 = safeParseJSON('{"name":"Alice"}'); console.log(result1.success); // true console.log(result1.data); // { name: "Alice" } // 無効なJSONの場合 (末尾カンマ) const result2 = safeParseJSON('{"name":"Alice",}'); console.log(result2.success); // false console.log(result2.data); // null </syntaxhighlight> <br><br> == JSON.stringify == ==== 基本的な使用方法 ==== <code>JSON.stringify(value, replacer, space)</code> は、JavaScriptの値をJSON文字列に変換するメソッドである。<br> <br> * <code>value</code> *: シリアライズ対象の値 * <code>replacer</code> *: フィルタリング関数 または 配列 (省略可能) * <code>space</code> *: インデントの指定 (省略可能) <br> 基本的な使用例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const obj = { name: "Alice", age: 30, active: true }; // 基本的なシリアライズ const json = JSON.stringify(obj); console.log(json); // '{"name":"Alice","age":30,"active":true}' // 配列のシリアライズ const arr = [1, "hello", true, null]; console.log(JSON.stringify(arr)); // '[1,"hello",true,null]' </syntaxhighlight> <br> ==== replacer引数 ==== ===== replacer関数 ===== replacerとして関数を指定した場合、オブジェクトの各プロパティに対してその関数が呼び出される。<br> <br> <u>undefined</u>、関数、または <u>Symbol</u> を返したプロパティは出力から除外される。<br> <br> <syntaxhighlight lang="javascript"> const user = { id: 1, name: "Alice", password: "secret123", apiKey: "key-xxxx-yyyy" }; // 機密情報を除外するreplacer関数 const safeJson = JSON.stringify(user, (key, value) => { if (key === 'password' || key === 'apiKey') return undefined; return value; }); console.log(safeJson); // '{"id":1,"name":"Alice"}' // 数値を文字列に変換するreplacer関数 const data = { count: 42, label: "items" }; const converted = JSON.stringify(data, (key, value) => { if (typeof value === 'number') return String(value); return value; }); console.log(converted); // '{"count":"42","label":"items"}' </syntaxhighlight> <br> ===== replacer配列 ===== replacerとして文字列の配列を指定した場合、配列に含まれるキーのプロパティのみが出力される。(ホワイトリスト方式)<br> <br> <syntaxhighlight lang="javascript"> const user = { id: 1, name: "Alice", email: "alice@example.com", password: "secret", role: "admin" }; // id, name, emailのみを含む const publicInfo = JSON.stringify(user, ['id', 'name', 'email']); console.log(publicInfo); // '{"id":1,"name":"Alice","email":"alice@example.com"}' </syntaxhighlight> <br> ==== space引数 ==== <code>space</code> 引数を指定することにより、出力JSONに読みやすいインデントを追加できる。<br> <br> * 数値を指定した場合 *: 指定したスペース数でインデントされる。(最大10) * 文字列を指定した場合 *: その文字列でインデントされる。(最大10文字) <br> <syntaxhighlight lang="javascript"> const obj = { name: "Alice", scores: [85, 92, 78] }; // 数値でインデント console.log(JSON.stringify(obj, null, 2)); // { // "name": "Alice", // "scores": [ // 85, // 92, // 78 // ] // } // タブ文字でインデント console.log(JSON.stringify(obj, null, '\t')); // { // "name": "Alice", // "scores": [...] // } </syntaxhighlight> <br> ==== toJSON()メソッド ==== オブジェクトに <code>toJSON()</code> メソッドが定義されている場合、<code>JSON.stringify</code> はオブジェクト自体ではなく <code>toJSON()</code> の戻り値をシリアライズする。<br> <br> <code>Date</code> オブジェクトはこの仕組みを組み込みで持っており、<code>toISOString()</code> と同等の結果を返す。<br> <br> <syntaxhighlight lang="javascript"> // DateオブジェクトのtoJSON() const date = new Date('2024-01-15T10:30:00.000Z'); console.log(JSON.stringify(date)); // '"2024-01-15T10:30:00.000Z"' // カスタムクラスでのtoJSON()実装 class Temperature { constructor(celsius) { this.celsius = celsius; } get fahrenheit() { return this.celsius * 9 / 5 + 32; } toJSON() { // シリアライズ時にcelsiusとfahrenheitの両方を含める return { celsius: this.celsius, fahrenheit: this.fahrenheit }; } } const temp = new Temperature(100); console.log(JSON.stringify(temp)); // '{"celsius":100,"fahrenheit":212}' </syntaxhighlight> <br><br> == シリアライズの注意点 == ==== 無視・変換される値 ==== <code>JSON.stringify</code> のシリアライズ時に、JavaScriptの値がどのように変換されるか下表に示す。<br> <br> <center> {| class="wikitable" |+ シリアライズ時の値の変換 ! 型 !! オブジェクトプロパティ値 !! 配列要素 !! トップレベル |- | undefined || 省略 (プロパティが削除) || null || undefined (文字列化されない) |- | function || 省略 (プロパティが削除) || null || undefined (文字列化されない) |- | Symbol || 省略 (プロパティが削除) || null || undefined (文字列化されない) |- | NaN || "null" (文字列) || "null" (文字列) || "null" (文字列) |- | Infinity || "null" (文字列) || "null" (文字列) || "null" (文字列) |- | BigInt || TypeError が発生 || TypeError が発生 || TypeError が発生 |} </center> <br> 具体的な動作例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const obj = { name: "Alice", fn: function() {}, // 省略される sym: Symbol("id"), // 省略される undef: undefined, // 省略される nan: NaN, // null になる inf: Infinity // null になる }; console.log(JSON.stringify(obj)); // '{"name":"Alice","nan":null,"inf":null}' // 配列要素では、nullに変換される const arr = [1, undefined, function() {}, Symbol("x"), NaN]; console.log(JSON.stringify(arr)); // '[1,null,null,null,null]' // BigIntはTypeErrorをスローする try { JSON.stringify({ value: 42n }); } catch (e) { console.log(e instanceof TypeError); // true } </syntaxhighlight> <br> ==== Dateオブジェクト ==== <code>Date</code> オブジェクトは <code>toJSON()</code> メソッドを持ち、<code>toISOString()</code> と同等のISO 8601形式の文字列に自動変換される。<br> ただし、<code>JSON.parse</code> は文字列をDateオブジェクトに戻す機能を持たないため、reviver関数を使用して明示的に変換する必要がある。<br> <br> <syntaxhighlight lang="javascript"> // シリアライズ : DateがISO文字列に変換される const event = { title: "ミーティング", date: new Date("2024-06-15T09:00:00.000Z") }; const json = JSON.stringify(event); console.log(json); // '{"title":"ミーティング","date":"2024-06-15T09:00:00.000Z"}' // デシリアライズ : reviver関数でDateを復元する const restored = JSON.parse(json, (key, value) => { if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) { return new Date(value); } return value; }); console.log(restored.date instanceof Date); // true console.log(restored.date.getFullYear()); // 2024 </syntaxhighlight> <br> ==== 循環参照 ==== オブジェクトが循環参照を持つ場合、<code>JSON.stringify</code> は <u>TypeError</u> をスローする。<br> <code>WeakSet</code> を使用することで、循環参照を検出してその箇所を除外するreplacer関数を定義できる。<br> <br> <syntaxhighlight lang="javascript"> // 循環参照を持つオブジェクト const obj = { name: "Alice" }; obj.self = obj; // 循環参照 try { JSON.stringify(obj); } catch (e) { console.log(e instanceof TypeError); // true console.log(e.message); // "Converting circular structure to JSON" } // WeakSetを使用した循環参照の回避 const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === 'object' && value !== null) { if (seen.has(value)) { return undefined; // 循環参照をundefinedで置換して除外する } seen.add(value); } return value; }; }; const safeJson = JSON.stringify(obj, getCircularReplacer()); console.log(safeJson); // '{"name":"Alice"}' </syntaxhighlight> <br> ==== Map / Set / RegExp ==== <u><code>Map</code>、<code>Set</code>、<code>RegExp</code> はいずれもJSONで直接表現できないため、シリアライズ時に情報が失われる。</u><br> <u>これらの型を正しくシリアライズするには、事前に変換処理が必要である。</u><br> <br> <syntaxhighlight lang="javascript"> // MapとSetはそのままでは空オブジェクト / 配列になる const map = new Map([["key1", "value1"], ["key2", "value2"]]); const set = new Set([1, 2, 3]); const regex = /hello/gi; console.log(JSON.stringify({ map, set, regex })); // '{"map":{},"set":{},"regex":{}}' // 全て空オブジェクト // Mapのシリアライズ: Object.fromEntries() または スプレッド構文で変換する const mapAsObject = Object.fromEntries(map); console.log(JSON.stringify(mapAsObject)); // '{"key1":"value1","key2":"value2"}' // Mapをエントリ配列として保存する場合 const mapAsArray = [...map]; console.log(JSON.stringify(mapAsArray)); // '[["key1","value1"],["key2","value2"]]' // Setのシリアライズ: 配列に変換する const setAsArray = [...set]; console.log(JSON.stringify(setAsArray)); // '[1,2,3]' // RegExpのシリアライズ: sourceとflagsを保存する const regexObj = { source: regex.source, flags: regex.flags }; console.log(JSON.stringify(regexObj)); // '{"source":"hello","flags":"gi"}' // RegExpの復元 const restoredRegex = new RegExp(regexObj.source, regexObj.flags); console.log(restoredRegex); // /hello/gi </syntaxhighlight> <br><br> == ディープコピー == ==== JSON.parse(JSON.stringify())によるディープコピー ==== <code>JSON.parse(JSON.stringify(obj))</code> は、オブジェクトのディープコピーを作成する最も単純な手法である。<br> <br> <u>外部ライブラリなしで定義でき、パフォーマンスも良好であるが、JSONで表現できない型は失われる点に注意が必要である。</u><br> <br> <syntaxhighlight lang="javascript"> const original = { name: "Alice", scores: [85, 92, 78], address: { city: "Tokyo", country: "Japan" } }; // ディープコピーを作成する const copy = JSON.parse(JSON.stringify(original)); // コピーを変更しても元のオブジェクトに影響しない copy.scores.push(100); copy.address.city = "Osaka"; console.log(original.scores); // [85, 92, 78] (変更されない) console.log(original.address.city); // "Tokyo" (変更されない) // 注意 : JSONで表現できない型は失われる const withSpecialTypes = { date: new Date("2024-01-01"), fn: function() {}, undef: undefined, regex: /hello/ }; const copied = JSON.parse(JSON.stringify(withSpecialTypes)); console.log(typeof copied.date); // "string" (Dateが文字列になる) console.log(copied.fn); // undefined (関数が削除) console.log(copied.undef); // undefined (プロパティが存在しない) console.log(copied.regex); // {} (RegExpが空オブジェクトになる) </syntaxhighlight> <br> ==== structuredClone()との比較 ==== <code>structuredClone()</code> は、Structured Clone アルゴリズムを使用してオブジェクトのディープコピーを作成する組み込み関数である。<br> <code>Date</code>、<code>Map</code>、<code>Set</code>、循環参照を正しく処理できる点がJSON方式と異なる。<br> <br> Webブラウザの対応状況として、Chrome 98+, Firefox 94+, Safari 15.4+, Node.js 17.0+ 以降で使用できる。<br> <br> <center> {| class="wikitable" |+ ディープコピー手法の比較 ! データ型 !! JSON方式 !! structuredClone() |- | 基本型 (string, number, boolean, null) || 正常にコピー || 正常にコピー |- | Date || 文字列に変換 (型が変わる) || Dateオブジェクトとして正しくコピー |- | Map || 空オブジェクト {} (情報が失われる) || Mapとして正しくコピー |- | Set || 空オブジェクト {} (情報が失われる) || Setとして正しくコピー |- | RegExp || 空オブジェクト {} (情報が失われる) || フラグを含めて正しくコピー |- | 関数 || 削除される || TypeError が発生 (コピー不可) |- | undefined || 削除される || 正常にコピー |- | Symbol || 削除される || TypeError が発生 (コピー不可) |- | BigInt || TypeError が発生 || 正常にコピー |- | 循環参照 || TypeError が発生 || 正常に処理 |} </center> <br> <code>structuredClone()</code> の使用例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const original = { name: "Alice", createdAt: new Date("2024-01-15"), tags: new Set(["js", "web"]), metadata: new Map([["version", "1.0"]]) }; // structuredClone()でコピーする const copy = structuredClone(original); console.log(copy.createdAt instanceof Date); // true (Dateが保持される) console.log(copy.tags instanceof Set); // true (Setが保持される) console.log(copy.metadata instanceof Map); // true (Mapが保持される) // 循環参照も正しくコピーできる const circular = { name: "test" }; circular.self = circular; const circularCopy = structuredClone(circular); console.log(circularCopy.self === circularCopy); // true (循環参照が維持される) </syntaxhighlight> <br><br> == TauriでのJSON活用 == Tauri v2では、JavaScriptフロントエンドとRustバックエンド間のIPC通信において、JSON形式でデータが受け渡される。<br> <br> <code>invoke()</code> 関数の引数と戻り値は自動的にシリアライズ・デシリアライズされる。<br> <br> データフローを以下に示す。<br> * JavaScript側 --> <code>JSON.stringify</code> (自動) --> IPC通信 * IPC通信 --> <code>serde_json</code> (自動) --> Rust構造体 * Rust構造体 --> <code>serde_json</code> (自動) --> IPC通信 * IPC通信 --> <code>JSON.parse</code> (自動) --> JavaScript側 <br> ==== invoke()によるデータ受け渡し ==== <code>invoke()</code> はJavaScriptからRustのコマンドを呼び出す関数であり、常にPromiseを返す。<br> 引数はオブジェクト形式で渡し、Rust側のコマンドのパラメータ名と一致させる必要がある。<br> <br> <syntaxhighlight lang="javascript"> import { invoke } from '@tauri-apps/api/core'; // 文字列を送受信する基本的な例 const result = await invoke('my_command', { message: 'Hello, Tauri!' }); console.log(result); // Rust側から返ってきた文字列 // オブジェクトを送受信する例 const userData = { firstName: "Alice", lastName: "Smith", isPremium: true }; const response = await invoke('process_user', { user: userData }); console.log(response); </syntaxhighlight> <br> 対応するRust側のコマンド定義を以下に示す。<br> <br> <syntaxhighlight lang="rust"> #[tauri::command] fn my_command(message: String) -> String { format!("受信: {}", message) } </syntaxhighlight> <br> ==== Rustの構造体とJSONの対応 ==== RustでJSONとの相互変換を行うには、<code>serde</code> クレート と <code>serde_json</code> クレートを使用する。<br> <code>#[derive(Serialize, Deserialize)]</code> アトリビュートを付与することにより、構造体の自動変換が有効になる。<br> <br> JavaScriptではキャメルケース、Rustではスネークケースが慣習となっているため、<code>#[serde(rename_all = "camelCase")]</code> アトリビュートを使用してフィールド名の変換ルールを設定することが推奨される。<br> <br> <syntaxhighlight lang="rust"> use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct UserData { first_name: String, // JSON上では: firstName last_name: String, // JSON上では: lastName is_premium: bool // JSON上では: isPremium } #[tauri::command] fn process_user(user: UserData) -> UserData { println!("名前: {} {}", user.first_name, user.last_name); user // そのまま返す } </syntaxhighlight> <br> JavaScript側から以下に示すように呼び出す。<br> <br> <syntaxhighlight lang="javascript"> import { invoke } from '@tauri-apps/api/core'; // camelCaseのキーでオブジェクトを送る const result = await invoke('process_user', { user: { firstName: "Alice", lastName: "Smith", isPremium: true } }); // 戻り値もcamelCaseで受け取る console.log(result.firstName); // "Alice" console.log(result.isPremium); // true </syntaxhighlight> <br> ==== 複雑なデータ構造の受け渡し ==== Rustの主要なデータ型とJSONの対応を以下に示す。<br> <br> ===== Vec<T> (配列) ===== Rustの <code>Vec<T></code> はJSONの配列として受け渡される。<br> <br> <syntaxhighlight lang="rust"> use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] struct Item { id: u32, name: String } #[tauri::command] fn process_items(items: Vec<Item>) -> u32 { items.len() as u32 } </syntaxhighlight> <br> <syntaxhighlight lang="javascript"> import { invoke } from '@tauri-apps/api/core'; const count = await invoke('process_items', { items: [ { id: 1, name: "Item A" }, { id: 2, name: "Item B" } ] }); console.log(count); // 2 </syntaxhighlight> <br> ===== Option<T> (null許容値) ===== Rustの <code>Option<T></code> は、<code>Some(value)</code> が値そのものに、<code>None</code> が <code>null</code> にマッピングされる。<br> <br> <syntaxhighlight lang="rust"> use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct Profile { name: String, middle_name: Option<String> // null の可能性あり } #[tauri::command] fn get_profile(has_middle: bool) -> Profile { Profile { name: "Alice".to_string(), middle_name: if has_middle { Some("Marie".to_string()) } else { None } } } </syntaxhighlight> <br> <syntaxhighlight lang="javascript"> import { invoke } from '@tauri-apps/api/core'; const profile1 = await invoke('get_profile', { hasMiddle: true }); console.log(profile1.middleName); // "Marie" const profile2 = await invoke('get_profile', { hasMiddle: false }); console.log(profile2.middleName); // null </syntaxhighlight> <br> ===== Enum (列挙型) ===== Rustの列挙型は <code>#[serde(tag = "type")]</code> アトリビュートを使用することで、JavaScriptのオブジェクトにマッピングできる。<br> <br> <syntaxhighlight lang="rust"> use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] #[serde(tag = "type")] enum RequestType { Create { name: String }, Update { id: u32, name: String }, Delete { id: u32 } } #[tauri::command] fn handle_request(request: RequestType) -> String { match request { RequestType::Create { name } => format!("作成: {}", name), RequestType::Update { id, name } => format!("更新: id={}, name={}", id, name), RequestType::Delete { id } => format!("削除: id={}", id) } } </syntaxhighlight> <br> <syntaxhighlight lang="javascript"> import { invoke } from '@tauri-apps/api/core'; // Createリクエスト const res1 = await invoke('handle_request', { request: { type: 'Create', name: 'New Item' } }); console.log(res1); // "作成: New Item" // Updateリクエスト const res2 = await invoke('handle_request', { request: { type: 'Update', id: 42, name: 'Updated Item' } }); console.log(res2); // "更新: id=42, name=Updated Item" // Deleteリクエスト const res3 = await invoke('handle_request', { request: { type: 'Delete', id: 42 } }); console.log(res3); // "削除: id=42" </syntaxhighlight> <br><br> == 関連情報 == * [[JavaScriptの基礎 - Fetch API]] *: Promiseを返すFetch APIによるHTTPリクエストの定義 * [[JavaScriptの基礎 - Promise]] *: Promiseの基本構文から静的メソッド、Tauriでの使用例 * [[JavaScriptの基礎 - async await]] *: Promiseをより簡潔に記述するためのasync / await構文の詳細 * [[JavaScriptの基礎 - エラーハンドリング]] *: try / catch、カスタムエラー、エラーの伝播 <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Web]]
JavaScriptの基礎 - JSON
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse