Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10166] ファイルの概要

このコミットは、Go言語の仕様書(doc/go_spec.html)にrune型を導入するものです。rune型は、Unicodeコードポイントを表現するための型としてGo言語に組み込まれ、文字列処理におけるUnicode対応を強化します。

コミット

  • コミットハッシュ: b910a2739629f10eea56c44467f99263ef303f46
  • Author: Robert Griesemer gri@golang.org
  • Date: Tue Nov 1 01:09:22 2011 -0400
  • コミットメッセージ:
    go spec: introduce rune type
    
    R=r, iant, rsc, r
    CC=golang-dev
    https://golang.org/cl/5293048
    

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/b910a2739629f10eea56c44467f99263ef303f46

元コミット内容

go spec: introduce rune type

R=r, iant, rsc, r
CC=golang-dev
https://golang.org/cl/5293048

変更の背景

Go言語は、現代のプログラミング言語として、多言語対応、特にUnicodeの適切な処理を重視しています。初期のコンピューターシステムではASCIIのような限られた文字セットが主流でしたが、グローバル化に伴い、世界中の多様な文字を扱う必要性が高まりました。Unicodeは、この課題を解決するために、地球上のほぼすべての文字に一意の番号(コードポイント)を割り当てる標準として開発されました。

Go言語の文字列はUTF-8エンコードされたバイト列として扱われます。しかし、UTF-8では多くのUnicode文字が複数バイトで表現されるため、単にバイト列として文字列を扱うだけでは、文字単位での正確な処理が困難になります。例えば、日本語の漢字や絵文字などは複数バイトで構成されるため、バイト単位で処理すると文字が途中で分断されたり、文字数が正しくカウントされなかったりする問題が発生します。

このような背景から、Go言語ではUnicodeコードポイントを明示的に扱うための新しい型としてruneが導入されました。このコミットは、そのrune型をGo言語の仕様書に正式に記述し、言語の基本的な要素として位置づけるものです。これにより、開発者は文字列をUnicodeコードポイントのシーケンスとしてより直感的に、かつ正確に操作できるようになります。

前提知識の解説

UnicodeとUTF-8

  • Unicode: 世界中のあらゆる文字を統一的に扱うための文字コード標準です。各文字には一意の「コードポイント」(整数値)が割り当てられています。例えば、'A'はU+0041、'あ'はU+3042といったコードポイントを持ちます。
  • UTF-8: Unicodeのコードポイントをバイト列にエンコード(符号化)するための可変長エンコーディング方式の一つです。ASCII文字は1バイトで表現され、それ以外の文字は2バイト以上で表現されます。これにより、ASCII互換性を保ちつつ、効率的にUnicode文字を表現できます。Go言語の文字列は内部的にUTF-8でエンコードされています。

Go言語におけるbytestring

  • byte: Go言語におけるbyte型はuint8のエイリアスであり、8ビットの符号なし整数を表します。主にバイトデータを扱う際に使用されます。Go言語の文字列はバイトのシーケンスであるため、string型を[]byteに変換することで、個々のバイトにアクセスできます。
  • string: Go言語のstring型は、不変なバイトのシーケンスです。内部的にはUTF-8でエンコードされたテキストを保持します。Goの文字列は、文字の集合ではなく、バイトの集合として扱われるため、文字列の長さをlen()関数で取得すると、バイト数が返されます。これは、マルチバイト文字を含む文字列の場合、実際の文字数とは異なる場合があります。

rune

rune型は、Go言語においてUnicodeコードポイントを表すために導入された型です。このコミットの時点ではintのエイリアスとされていますが、将来的にはint32のエイリアスとなることが示唆されています(実際にGo 1.0以降ではint32のエイリアスとなっています)。

  • Unicodeコードポイントの表現: runeは、単一のUnicodeコードポイントを表現します。これにより、UTF-8の複数バイトで構成される文字であっても、runeとして扱うことで1つの論理的な文字として処理できます。
  • 文字列のイテレーション: for rangeループで文字列をイテレートする際、Goは文字列をUTF-8デコードし、各イテレーションでUnicodeコードポイント(rune)と、そのコードポイントが文字列内で始まるバイトインデックスを返します。これにより、開発者は文字単位で文字列を安全に処理できます。
  • []runeスライス: 文字列を[]rune型に変換することで、文字列をUnicodeコードポイントのシーケンスとして扱うことができます。これは、文字単位での操作(例:文字の逆順、特定の文字の置換)を行う際に非常に便利です。

技術的詳細

このコミットは、Go言語の公式仕様書であるdoc/go_spec.htmlを修正し、rune型に関する記述を追加・変更しています。主な変更点は以下の通りです。

  1. rune型の導入:
    • byte型と同様に、rune型が新しい組み込み型として導入されました。
    • 当初はintのエイリアスとして定義され、将来的にint32のエイリアスになることが明記されています。これは、Unicodeコードポイントが最大でU+10FFFFまで存在し、これを表現するには32ビット整数が必要であるためです。
  2. 基本型への追加:
    • 仕様書の「Basic types」のリストにruneが追加されました。これにより、runeがGo言語の基本的なデータ型の一つとして認識されます。
  3. 組み込み関数deleteの追加:
    • このコミットでは、rune型の導入とは直接関係ありませんが、組み込み関数リストにdeleteが追加されています。これはマップから要素を削除するための関数です。
  4. 型変換の記述変更:
    • 文字列とスライス([]byte[]int)間の型変換に関する記述が更新されました。特に、[]int[]runeに置き換えられ、文字列からUnicodeコードポイントのスライスへの変換がより明確に[]runeとして扱われるようになりました。
    • string([]int{...})のような変換がstring([]rune{...})に変更され、[]int(MyString(...))のような変換が[]rune(MyString(...))に変更されています。これは、文字列がUnicodeコードポイントのシーケンスとして扱われることを強調しています。
  5. for rangeループのセマンティクス変更:
    • 文字列に対するfor rangeループのセマンティクスが更新されました。以前は2番目の値がint型とされていましたが、rune型の導入に伴い、2番目の値がrune型となることが明記されました。これにより、文字列のfor rangeループがUnicodeコードポイントを直接返すことが明確になります。

これらの変更は、Go言語がUnicodeを第一級の市民として扱い、開発者が多言語対応のアプリケーションをより容易に、かつ正確に構築できるようにするための重要なステップです。

コアとなるコードの変更箇所

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,5 +1,5 @@
 <!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of October 17, 2011 -->
+<!-- subtitle Version of October 25, 2011 -->
 
 <!--
 TODO
@@ -691,7 +691,8 @@ float64     the set of all IEEE-754 64-bit floating-point numbers
 complex64   the set of all complex numbers with float32 real and imaginary parts
 complex128  the set of all complex numbers with float64 real and imaginary parts
 
-byte        familiar alias for uint8
+byte        alias for uint8
+rune        alias for int (will change to int32 in the future)
 </pre>
 
 <p>
@@ -711,7 +712,9 @@ uintptr  an unsigned integer large enough to store the uninterpreted bits of a p
 
 <p>
 To avoid portability issues all numeric types are distinct except
-<code>byte</code>, which is an alias for <code>uint8</code>.
+<code>byte</code>, which is an alias for <code>uint8</code>, and
+<code>rune</code>, which is an alias for <code>int</code> (to become
+<code>int32</code> in a later version of Go).
 Conversions
 are required when different numeric types are mixed in an expression
 or assignment. For instance, <code>int32</code> and <code>int</code>
@@ -1497,7 +1500,7 @@ The following identifiers are implicitly declared in the universe block:\n <pre class=\"grammar\">\n Basic types:\n \tbool byte complex64 complex128 float32 float64\n-\tint8 int16 int32 int64 string uint8 uint16 uint32 uint64\n+\tint8 int16 int32 int64 rune string uint8 uint16 uint32 uint64\n \n Architecture-specific convenience types:\n \tint uint uintptr\n@@ -1509,7 +1512,7 @@ Zero value:\n \tnil\n \n Functions:\n-\tappend cap close complex copy imag len\n+\tappend cap close complex copy delete imag len\n \tmake new panic print println real recover\n </pre>\n \n@@ -1791,11 +1794,15 @@ constant:\n </p>\n \n <pre>\n-var b = true    // t has type bool\n-var i = 0       // i has type int\n-var f = 3.0     // f has type float64\n-var c = 1i      // c has type complex128\n-var s = \"OMDB\"  // s has type string\n+var b  = true    // t  has type bool\n+var r  = 'a'     // r  has type int\n+var i  = 0       // i  has type int\n+var f  = 3.0     // f  has type float64\n+var c0 = 0i      // c0 has type complex128\n+var c1 = 1 + 0i  // c1 has type complex128\n+var c2 = 1 + 1i  // c2 has type complex128\n+var s1 = "OMDB"  // s1 has type string\n+var s2 = `foo`   // s2 has type string\n </pre>\n \n <h3 id=\"Short_variable_declarations\">Short variable declarations\">Short variable declarations</h3>\n@@ -3276,11 +3283,11 @@ in any of these cases:\n \t</li>\n \t<li>\n \t<code>x</code> is an integer or has type <code>[]byte</code> or\n-\t<code>[]int</code> and <code>T</code> is a string type.\n+\t<code>[]rune</code> and <code>T</code> is a string type.\n \t</li>\n \t<li>\n \t<code>x</code> is a string and <code>T</code> is <code>[]byte</code> or\n-\t<code>[]int</code>.\n+\t<code>[]rune</code>.\n \t</li>\n </ul>\n \n@@ -3354,9 +3361,8 @@ MyString(0x65e5)      // "\\u65e5" == "日" == "\\xe6\\x97\\xa5"\n </li>\n \n <li>\n-Converting a value of type <code>[]byte</code> (or\n-the equivalent <code>[]uint8</code>) to a string type yields a\n-string whose successive bytes are the elements of the slice.  If\n+Converting a value of type <code>[]byte</code> to a string type yields\n+a string whose successive bytes are the elements of the slice.  If\n the slice value is <code>nil</code>, the result is the empty string.\n \n <pre>\n@@ -3365,12 +3371,13 @@ string([]byte{'h', 'e', 'l', 'l', '\\xc3', '\\xb8'})  // "hellø"\n </li>\n \n <li>\n-Converting a value of type <code>[]int</code> to a string type yields\n-a string that is the concatenation of the individual integers\n+Converting a value of type <code>[]rune</code> to a string type yields\n+a string that is the concatenation of the individual rune values\n converted to strings.  If the slice value is <code>nil</code>, the\n result is the empty string.\n+\n <pre>\n-string([]int{0x767d, 0x9d6c, 0x7fd4})  // "\\u767d\\u9d6c\\u7fd4" == "白鵬翔"\n+string([]rune{0x767d, 0x9d6c, 0x7fd4})  // "\\u767d\\u9d6c\\u7fd4" == "白鵬翔"\n </pre>\n </li>\n \n@@ -3385,11 +3392,11 @@ If the string is empty, the result is <code>[]byte(nil)</code>.\n </li>\n \n <li>\n-Converting a value of a string type to <code>[]int</code> yields a\n+Converting a value of a string type to <code>[]rune</code> yields a\n slice containing the individual Unicode code points of the string.\n-If the string is empty, the result is <code>[]int(nil)</code>.\n+If the string is empty, the result is <code>[]rune(nil)</code>.\n <pre>\n-[]int(MyString("白鵬翔"))  // []int{0x767d, 0x9d6c, 0x7fd4}\n+[]rune(MyString("白鵬翔"))  // []rune{0x767d, 0x9d6c, 0x7fd4}\n </pre>\n </li>\n </ol>\n@@ -4059,7 +4066,7 @@ For each iteration, iteration values are produced as follows:\n Range expression                          1st value          2nd value (if 2nd variable is present)\n \n array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E\n-string          s  string type            index    i  int    see below  int\n+string          s  string type            index    i  int    see below  rune\n map             m  map[K]V                key      k  K      m[k]       V\n channel         c  chan E                 element  e  E\n </pre>\n@@ -4077,7 +4084,7 @@ or slice itself. For a <code>nil</code> slice, the number of iterations is 0.\n For a string value, the "range" clause iterates over the Unicode code points\n in the string starting at byte index 0.  On successive iterations, the index value will be the\n index of the first byte of successive UTF-8-encoded code points in the string,\n-and the second value, of type <code>int</code>, will be the value of\n+and the second value, of type <code>rune</code>, will be the value of\n the corresponding code point.  If the iteration encounters an invalid\n UTF-8 sequence, the second value will be <code>0xFFFD</code>,\n the Unicode replacement character, and the next iteration will advance\n```

## コアとなるコードの解説

上記の差分は、Go言語の仕様書(`doc/go_spec.html`)における`rune`型の導入と、それに伴う関連記述の変更を示しています。

1.  **仕様書のバージョン日付の更新**:
    ```diff
    -<!-- subtitle Version of October 17, 2011 -->
    +<!-- subtitle Version of October 25, 2011 -->
    ```
    これは、仕様書が更新された日付を示しています。

2.  **`rune`型の定義の追加**:
    ```diff
    -byte        familiar alias for uint8
    +byte        alias for uint8
    +rune        alias for int (will change to int32 in the future)
    ```
    `byte`の記述が「familiar alias」から単に「alias」に変更され、その下に`rune`型が追加されました。`rune`は`int`のエイリアスであり、将来的に`int32`になることが明記されています。これは、Unicodeコードポイントが32ビット整数で表現されるためです。

3.  **型に関する説明の更新**:
    ```diff
    -<code>byte</code>, which is an alias for <code>uint8</code>.
    +<code>byte</code>, which is an alias for <code>uint8</code>, and
    +<code>rune</code>, which is an alias for <code>int</code> (to become
    +<code>int32</code> in a later version of Go).
    ```
    `byte`が`uint8`のエイリアスであることに加えて、`rune`が`int`のエイリアスであり、将来的に`int32`になることが追記されました。これにより、`byte`と`rune`がGo言語における特別なエイリアス型として位置づけられます。

4.  **基本型リストへの`rune`の追加**:
    ```diff
    -	int8 int16 int32 int64 string uint8 uint16 uint32 uint64
    +	int8 int16 int32 int64 rune string uint8 uint16 uint32 uint64
    ```
    Go言語の基本型リストに`rune`が追加されました。これは、`rune`が`bool`, `string`, `int`などと同様に、Go言語の基本的なデータ型の一つであることを示しています。

5.  **組み込み関数リストへの`delete`の追加**:
    ```diff
    -	append cap close complex copy imag len
    +	append cap close complex copy delete imag len
    ```
    組み込み関数`delete`がリストに追加されました。これはマップから要素を削除するために使用されます。この変更は`rune`の導入とは直接関係ありませんが、同じコミットで含まれています。

6.  **変数宣言の例の追加と修正**:
    ```diff
    -var b = true    // t has type bool
    -var i = 0       // i has type int
    -var f = 3.0     // f has type float64
    -var c = 1i      // c has type complex128
    -var s = "OMDB"  // s has type string
    +var b  = true    // t  has type bool
    +var r  = 'a'     // r  has type int
    +var i  = 0       // i  has type int
    +var f  = 3.0     // f  has type float64
    +var c0 = 0i      // c0 has type complex128
    +var c1 = 1 + 0i  // c1 has type complex128
    +var c2 = 1 + 1i  // c2 has type complex128
    +var s1 = "OMDB"  // s1 has type string
    +var s2 = `foo`   // s2 has type string
    ```
    変数宣言の例が拡張され、特に`var r = 'a'`のようにシングルクォートで囲まれた文字リテラルが`int`型(つまり`rune`型)を持つことが示されています。これは、Go言語において文字リテラルがUnicodeコードポイントを表す`rune`型として扱われることを明確にしています。また、複数の複素数型や文字列リテラルの例も追加されています。

7.  **文字列とスライス間の型変換の更新**:
    ```diff
    -	<code>[]int</code> and <code>T</code> is a string type.
    +	<code>[]rune</code> and <code>T</code> is a string type.
    ```
    ```diff
    -	<code>[]int</code>.
    +	<code>[]rune</code>.
    ```
    ```diff
    -Converting a value of type <code>[]int</code> to a string type yields
    -a string that is the concatenation of the individual integers
    +Converting a value of type <code>[]rune</code> to a string type yields
    +a string that is the concatenation of the individual rune values
    ```
    ```diff
    -string([]int{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    ```
    ```diff
    -Converting a value of a string type to <code>[]int</code> yields a
    +Converting a value of a string type to <code>[]rune</code> yields a
    ```
    ```diff
    -If the string is empty, the result is <code>[]int(nil)</code>.
    +If the string is empty, the result is <code>[]rune(nil)</code>.
    ```
    ```diff
    -[]int(MyString("白鵬翔"))  // []int{0x767d, 0x9d6c, 0x7fd4}
    +[]rune(MyString("白鵬翔"))  // []rune{0x767d, 0x9d6c, 0x7fd4}
    ```
    これらの変更は、文字列とスライス間の変換において、Unicodeコードポイントを扱う際に`[]int`ではなく`[]rune`を使用することを明確にしています。これにより、文字列がバイト列であると同時に、Unicodeコードポイントのシーケンスとしても扱えるというGo言語の設計思想が強調されます。

8.  **`for range`ループにおける文字列の2番目の値の型の変更**:
    ```diff
    -string          s  string type            index    i  int    see below  int
    +string          s  string type            index    i  int    see below  rune
    ```
    ```diff
    -and the second value, of type <code>int</code>, will be the value of
    +and the second value, of type <code>rune</code>, will be the value of
    ```
    文字列に対する`for range`ループにおいて、2番目の値(つまり、デコードされたUnicodeコードポイント)の型が`int`から`rune`に変更されました。これは、`for range`ループが文字列をUnicodeコードポイントのシーケンスとしてイテレートし、各コードポイントを`rune`型として提供することを明確に示しています。これにより、開発者は文字列を文字単位で安全かつ直感的に処理できるようになります。

これらの変更は、Go言語がUnicodeをネイティブにサポートし、開発者が多言語対応のアプリケーションをより容易に構築できるようにするための基盤を強化するものです。

## 関連リンク

*   GitHubコミットページ: [https://github.com/golang/go/commit/b910a2739629f10eea56c44467f99263ef303f46](https://github.com/golang/go/commit/b910a2739629f10eea56c44467f99263ef303f46)
*   Go Code Review (CL): [https://golang.org/cl/5293048](https://golang.org/cl/5293048)

## 参考にした情報源リンク

*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGVbuw5CZRy6dyKTLqjga5-xKJEHJ51SBdqVynjmjfy0kLBcwKqhFc37bA9-80fgVwwGmz41IB69kjN4WCNCYJjRWDB5MqRWU0j9UzxQabh6HA-MCnUCE72Ir1s43SNImJCwfDDL8juCNTfw3GAKQmpfVbBpqJvlzREV4Ehmi3eDama9fuTY3BPOLe1Cvs4pxdxY-QGMgOuyCXAP-_SBIIp6-FFbn7JZWsHY3wGBl6EW7Z466UTYw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGVbuw5CZRy6dyKTLqjga5-xKJEHJ51SBdqVynjmjfy0kLBcwKqhFc37bA9-80fgVwwGmz41IB69kjN4WCNCYJjRWDB5MqRWU0j9UzxQabh6HA-MCnUCE72Ir1s43SNImJCwfDDL8juCNTfw3BPOLe1Cvs4pxdxY-QGMgOuyCXAP-_SBIIp6-FFbn7JZWsHY3wGBl6EW7Z466UTYw==)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQElpPUvuavIebtGfkWnw9anTum5Lusu048FDV1k6qmnfrNepDjnpFNPkbafds-RhOuY2LZy7Lb0APva0yHkC1Mzyuag9Qfpi8XAjxpLtV4iUdnRdlp7GyjD5l-sH5Fd5BCwdTc2eFNohmarp0Kg8vPpwHCa-wU=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQElpPUvuavIebtGfkWnw9anTum5Lusu048FDV1k6qmnfrNepDjnpFNPkbafds-RhOuY2LZy7Lb0APva0yHkC1Mzyuag9Qfpi8XAjxpLtV4iUdnRdlp7GyjD5l-sH5Fd5BCwdTc2eFNohmarp0Kg8vPpwHCa-wU=)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEMfPgzGfrj7JO5d5V0YuKGQnA-hR1YBsZtEvRH3243Zi7TaOJDhtjyRGl1rvswVwsFz7O74lrRMCydNBtNwMUpxj_tyDPlCkOgacghuLFRNXBLx8XRJ_vOs9DsrLXkhiWqbCLMF3DS-L_b1RzmmI9wjU95hri](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEMfPgzGfrj7JO5d5V0YuKGQnA-hR1YBsZtEvRH3243Zi7TaOJDhtjyRGl1rvswVwsFz7O74lrRMCydNBtNwMUpxj_tyDPlCkOgacghuLFRNXBLx8XRJ_vOs9DsrLXkhiWqbCLMF3DS-L_b1RzmmI9wjU95hri)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFJPi-Ab8mPZJwTT_ZaTDK6yJVu0y_awhsb6Qkm2MjMCIaTszWXQMYAQxqF7q-8ZBFGyxcxYRDD__eFJ7n61b3n1XBu-XnpJ1hSRz_HUvjTOfFuuDXInMhSTn76od50IkpHSeg3IG2Jxtme2yVOuKhH4hYO](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFJPi-Ab8mPZJwTT_ZaTDK6yJVu0y_awhsb6Qkm2MjMCIaTszWXQMYAQxqF7q-8ZBFGyxcxYRDD__eFJ7n61b3n1XBu-XnpJ1hSRz_HUvjTOfFuuDXInMhSTn76od50IkpHSeg3IG2Jxtme2yVOuKhH4hYO)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHlxnOMdQRlnxjxr7mp7gxH14PbC9eqLq5XX9KjtAjbJwhM44gS8sx7I-S56NPtCgPMzJIKL1XnpEsj1hSBgJGGlBDsVz2ll0nk0UvyFT9VV59q4gO9vyD7Vbvir5M-KbY2wMD9dWQGNDDRCEPIppli5sa5ArCJh-GZTPjzYNQL1rk34J8=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHlxnOMdQRlnxjxr7mp7gxH14PbC9eqLq5XX9KjtAjbJwhM44gS8sx7I-S56NPtCgPMzJIKL1XnpEsj1hSBgJGGlBDsVz2ll0nk0UvyFT9VV59q4gO9vyD7Vbvir5M-KbY2wMD9dWQGNDDRCEPIppli5sa5ArCJh-GZTPjzYNQL1rk34J8=)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHNwClCqqTGWzTHVLsroybKMCEqmkukiHJKGF5xpljXC74IyNvTf4JjTXN1jAii0Pb26VtuLeldG6dQpqOmyq-fkFxl-pcKA0PEN5FZ_e2y7diya0LfrwV-y7_apNYCuR2yDuZ2teqq7LfxpAM=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHNwClCqqTGWzTHVLsroybKMCEqmkukiHJKGF5xpljXC74IyNvTf4JjTXN1jAii0Pb26VtuLeldG6dQpqOmyq-fkFxl-pcKA0PEN5FZ_e2y7diya0LfrwV-y7_apNYCuR2yDuZ2teqq7LfxpAM=)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGIj77ZPpM2KR1gJEdjNMbheS9f0fqJ5F5WJ8m4ACmYJ0ow_HJN1eSA2ZKsgsn18tC960SW5weIW8XtxrmOkLxum_NPywKeJOaZ19x_zWPiuV1vVZUrkhJPFHgvh3aiUKhc0HcGTo_PoWCWa_NRDfWCxLhPFl92_nMyceQRsH-UjkgEWh6fHXWQZEoYFHzT1X7TfEJYLHyJAb2AvWDGY8-SjgXETBuDBQDB](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGIj77ZPpM2KR1gJEdjNMbheS9f0fqJ5F5WJ8m4ACmYJ0ow_HJN1eSA2ZKsgsn18tC960SW5weIW8XtxrmOkLxum_NPykKeJOaZ19x_zWPiuV1vVZUrkhJPFHgvh3aiUKhc0HcGTo_PoWCWa_NRDfWCxLhPFl92_nMyceQRsH-UjkgEWh6fHXWQZEoYFHzT1X7TfEJYLHyJAb2AvWDGY8-SjgXETBuDBQDB)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG2HG1tXspkwKBLZeovhLQcNTjnZ80zmq5U4-bivjMgsuHuaeeJdlm91sRnAheRb0ZWmR_RO0XGATOndyPeyeb1Sy4Kz4od94rNDOQk_2-rcZ9P6_MhRSkpdb-g63n9XE_onKMljHe3w1ncugJ2C9-SDJBBMkdodg==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQG2HG1tXspkwKBLZeovhLQcNTjnZ80zmq5U4-bivjMgsuHuaeeJdlm91sRnAheRb0ZWmR_RO0XGATOndyPeyeb1Sy4Kz4od94rNDOQk_2-rcZ9P6_MhRSkpdb-g63n9XE_onKMljHe3w1ncugJ2C9-SDJBBMkdodg==)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHVz0sRpyDkpWJUp-_ExsOHDUJ3tTM2j65pQH_M8a71q4ZHlwBjUWUuEbg0Q_L1_S1v0TZqej8UQt1qHBXDK6wtiKdWG2ENAsLg-bqc0JuIBm1pMau32oCvGXGJnQXi3YFRwlYvS-pIzqtXx6VqXpPk6eOZ4RXWArxB18bF](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHVz0sRpyDkpWJUp-_ExsOHDUJ3tTM2j65pQH_M8a71q4ZHlwBjUWUuEbg0Q_L1_S1v0TZqej8UQt1qHBXDK6wtiKdWG2ENAsLg-bqc0JuIBm1pMau32oCvGXGJnQXi3YFRwlYvS-pIzqtXx6VqXpPk6eOZ4RXWArxB18bF)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFPSHqz_c_5YKVylp6gq40IJHSn0p9hM2dZExN239WyVde9c8Cr8Bx1ze13RywGCoIZENUEeTjMTIe4LYh1u-adfKY9pTIRGiS3-gnM05y_rnANuE8oVPSeionQBG3UD-Fc6zglIFXA](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFPSHqz_c_5YKVylp6gq40IJHSn0p9hM2dZExN239WyVde9c8Cr8Bx1ze13RywGCoIZENUEeTjMTIe4LYh1u-adfKY9pTIRGiS3-gnM05y_rnANuE8oVPSeionQBG3UD-Fc6zglIFXA)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFxnSgnFYYziZUWraWlWJyZdAc95IRrBBfflSaH4Wc18h1QwkblGd095plS7yFsOAUZnAtczL2dTQXJO0mm6TK_2FrlQrZxn5BSvK7LQRM1mxSb64Fr2g1JTQaYeKfCQWLdC1CD2v47wn6Swiyd2WjLD3py8Sc=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFxnSgnFYYziZUWraWlWJyZdAc95IRrBBfflSaH4Wc18h1QwkblGd095plS7yFsOAUZnAtczL2dTQXJO0mm6TK_2FrlQrZxn5BSvK7LQRM1mxSb64Fr2g1JTQaYeKfCQWLdC1CD2v47wn6Swiyd2WjLD3py8Sc=)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFZ-cYs4ap8s3FoI8g8qRduuBmp5v-Pcw5jizjDBR5KIDPHA8B72GMC5WNOiC2GfDCr_J_w7XWjvqapMURgyK15GsIH9gSRpL9WD4tHC9gYK4qZ_VXNEuEAuuzKgfZTROU4j26KP-isI-Fy86dpJAlbjSL7x-6RHcWDE7vfs9uTw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFZ-cYs4ap8s3FoI8g8qRduuBmp5v-Pcw5jizjDBR5KIDPHA8B72GMC5WNOiC2GfDCr_J_w7XWjvqapMURgyK15GsIH9gSRpL9WD4tHC9gYK4qZ_VXNEuEAuuzKgfZTROU4j26KP-isI-Fy86dpJAlbjSL7x-6RHcWDE7vfs9uTw==)
*   [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH0Vd2pR9Izyvi0duTulz6kXOvM3_CHdyqFD32lXGNhttf39tua1rhCKpJeslRtmlArU8Nris9xnOAFKS9Vx7Xa9FPqZCeBbn5idGMKyKWZy1yvGKKP](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH0Vd2pR9Izyvi0duTulz6kXOvM3_CHdyqFD32lXGNhttf39tua1rhCKpJeslRtmlArU8Nris9xnOAFKS9Vx7Xa9FPqZCeBbn5idGMKyKWZy1yvGKKP)