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