[インデックス 10100] ファイルの概要
このコミットは、Go言語の標準ライブラリであるbig
パッケージにおけるfmt
インターフェースの変更に対応するためのものです。具体的には、fmt
パッケージのフォーマット関数やスキャン関数で使用される文字引数の型がint
からrune
に変更されたことに伴い、big
パッケージ内の関連する関数シグネチャが更新されています。
コミット
- コミットハッシュ:
0e513317b1fe148b4fd6604455bc89ecf44ed088
- Author: Russ Cox rsc@golang.org
- Date: Tue Oct 25 22:21:49 2011 -0700
- 変更ファイル:
src/pkg/big/int.go
src/pkg/big/nat.go
src/pkg/big/nat_test.go
src/pkg/big/rat.go
- 変更概要:
fmt
インターフェースの変更に対応するため、big
パッケージ内の関数引数の型をint
からrune
に更新。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0e513317b1fe148b4fd6604455bc89ecf44ed088
元コミット内容
big: update for fmt interface changes
Nothing terribly interesting here.
R=gri
CC=golang-dev
https://golang.org/cl/5305046
変更の背景
このコミットは、2011年10月26日にGo言語にrune
型が導入されたことと、それに伴うfmt
パッケージのインターフェース変更が背景にあります。
Go言語は当初、文字列をバイトのシーケンスとして扱っていましたが、Unicode文字の多様性を適切に扱うためには、バイトではなくUnicodeコードポイントを表現する新しい型が必要とされました。そこで導入されたのがrune
型です。rune
はGo 1のリリース前はint
のエイリアスとして定義されていましたが、Go 1以降はint32
のエイリアスとなり、単一のUnicodeコードポイントを表すようになりました。
fmt
パッケージは、Goにおけるフォーマット済みI/Oを扱うための重要なパッケージです。fmt.Formatter
インターフェースやfmt.Scanner
インターフェースは、カスタム型が自身のフォーマットやスキャン方法を定義するために使用されます。これらのインターフェースのメソッド(例: Format(s fmt.State, ch int)
)は、フォーマット指定子(例: %d
, %x
)を表す文字をint
型で受け取っていました。
rune
型の導入により、文字を扱う際のセマンティクスがより明確になったため、fmt
パッケージのインターフェースも、文字を表す引数をint
からrune
に変更する必要が生じました。この変更は、Go言語がUnicodeをより適切にサポートするための重要なステップでした。
big
パッケージは、任意精度の整数(Int
)、自然数(Nat
)、有理数(Rat
)を扱うためのパッケージであり、これらの型はfmt
パッケージのインターフェースを実装して、文字列への変換や文字列からのスキャンをサポートしています。そのため、fmt
インターフェースの変更に追従して、big
パッケージ内の関連するメソッドの引数型も更新する必要がありました。
前提知識の解説
Go言語のrune
型とint
型
int
型: Go言語のint
型は、符号付き整数型であり、そのサイズは少なくとも32ビットです。実際のサイズはプラットフォームに依存し、通常はCPUのアーキテクチャ(例: 64ビットシステムでは64ビット)に一致します。rune
型:rune
型はGo言語における組み込み型の一つで、Unicodeコードポイントを表します。これはint32
のエイリアスであり、単一のUnicode文字を表現するために使用されます。Goの文字列はUTF-8エンコードされたバイトのシーケンスですが、rune
を使用することで、マルチバイト文字を含むUnicode文字列を正しくイテレートし、処理することができます。
Go言語のfmt
パッケージとインターフェース
fmt
パッケージは、Go言語におけるフォーマット済みI/O(入出力)を実装するためのパッケージです。C言語のprintf
やscanf
に似た機能を提供します。
-
fmt.Formatter
インターフェース:type Formatter interface { Format(s State, verb rune) }
このインターフェースは、カスタム型が
fmt.Print
系の関数(fmt.Printf
,fmt.Sprint
など)によってどのようにフォーマットされるかを制御するために実装されます。Format
メソッドは、フォーマットの状態(fmt.State
)と、フォーマット動詞(例:%d
のd
、%x
のx
)を表すrune
型の引数を受け取ります。 -
fmt.Scanner
インターフェース:type Scanner interface { Scan(state ScanState, verb rune) error }
このインターフェースは、カスタム型が
fmt.Scan
系の関数(fmt.Scanf
,fmt.Sscan
など)によってどのようにスキャンされるかを制御するために実装されます。Scan
メソッドは、スキャンの状態(fmt.ScanState
)と、スキャン動詞を表すrune
型の引数を受け取ります。
このコミットが行われた時点では、これらのインターフェースのverb
引数はint
型でした。このコミットは、そのint
型をrune
型に変更するGo言語全体の変更に追従するものです。
技術的詳細
このコミットの技術的な核心は、Go言語のfmt
パッケージにおけるインターフェースの変更、特にフォーマット動詞やスキャン動詞を表す引数の型がint
からrune
へ移行したことにあります。
Go言語の初期段階では、文字を表現するためにint
型が広く使われていました。しかし、Unicodeの普及と、マルチバイト文字の適切な処理の必要性から、Unicodeコードポイントを明示的に扱うためのrune
型が導入されました。rune
型はint32
のエイリアスであり、これによりGoはより堅牢な国際化対応が可能になりました。
fmt
パッケージのFormat
メソッドやScan
メソッドは、フォーマット動詞(例: %d
のd
)を引数として受け取ります。これらの動詞は単一の文字であり、Unicodeコードポイントとして解釈されるべきです。したがって、これらの引数の型をint
からrune
に変更することは、Go言語の設計思想における一貫性を保ち、文字処理の正確性を向上させる上で自然な流れでした。
big
パッケージは、fmt.Formatter
とfmt.Scanner
インターフェースを実装しており、Int
, Nat
, Rat
といった任意精度の数値型を文字列として表現したり、文字列から解析したりする機能を提供しています。big
パッケージ内の以下の関数がこの変更の影響を受けました。
func charset(ch int) string
->func charset(ch rune) string
func (x *Int) Format(s fmt.State, ch int)
->func (x *Int) Format(s fmt.State, ch rune)
func (z *Int) Scan(s fmt.ScanState, ch int) os.Error
->func (z *Int) Scan(s fmt.ScanState, ch rune) os.Error
func hexValue(ch int) Word
->func hexValue(ch rune) Word
var natScanTests = []struct { ... next int ... }
->var natScanTests = []struct { ... next rune ... }
func ratTok(ch int) bool
->func ratTok(ch rune) bool
func (z *Rat) Scan(s fmt.ScanState, ch int) os.Error
->func (z *Rat) Scan(s fmt.ScanState, ch rune) os.Error
これらの変更は、単に引数の型をint
からrune
に置き換えるだけでなく、hexValue
関数内での文字から数値への変換(ch - '0'
など)の結果を明示的にint()
にキャストする変更も含まれています。これは、rune
がint32
のエイリアスであるため、算術演算の結果がint
型になることを保証するため、または将来的な型推論の変更に備えるための防御的なプログラミングであると考えられます。
このコミットは、Go言語の進化における小さな、しかし重要な一歩であり、言語全体でUnicodeの扱いを統一し、より堅牢な文字処理を可能にするための基盤を固めるものでした。
コアとなるコードの変更箇所
diff --git a/src/pkg/big/int.go b/src/pkg/big/int.go
index b0dde1e6e3..db13d20f71 100644
--- a/src/pkg/big/int.go
+++ b/src/pkg/big/int.go
@@ -302,7 +302,7 @@ func (x *Int) String() string {
return x.abs.decimalString()
}
-func charset(ch int) string {
+func charset(ch rune) string {
switch ch {
case 'b':
return lowercaseDigits[0:2]
@@ -339,7 +339,7 @@ func writeMultiple(s fmt.State, text string, count int) {
// output field width, space or zero padding, and left or
// right justification.
//
-func (x *Int) Format(s fmt.State, ch int) {
+func (x *Int) Format(s fmt.State, ch rune) {
cs := charset(ch)
// special cases
@@ -460,7 +460,7 @@ func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, os.Error) {
// Scan is a support routine for fmt.Scanner; it sets z to the value of
// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-func (z *Int) Scan(s fmt.ScanState, ch int) os.Error {
+func (z *Int) Scan(s fmt.ScanState, ch rune) os.Error {
s.SkipSpace() // skip leading space characters
base := 0
switch ch {
diff --git a/src/pkg/big/nat.go b/src/pkg/big/nat.go
index c0769d88a9..fa0d7e7227 100644
--- a/src/pkg/big/nat.go
+++ b/src/pkg/big/nat.go
@@ -589,15 +589,15 @@ func (x nat) bitLen() int {
// MaxBase is the largest number base accepted for string conversions.
const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1
-func hexValue(ch int) Word {
+func hexValue(ch rune) Word {
d := MaxBase + 1 // illegal base
switch {
case '0' <= ch && ch <= '9':
-\t\td = ch - '0'
+\t\td = int(ch - '0')
case 'a' <= ch && ch <= 'z':
-\t\td = ch - 'a' + 10
+\t\td = int(ch - 'a' + 10)
case 'A' <= ch && ch <= 'Z':
-\t\td = ch - 'A' + 10
+\t\td = int(ch - 'A' + 10)
}
return Word(d)
}
diff --git a/src/pkg/big/nat_test.go b/src/pkg/big/nat_test.go
index 4f5732824c..ab34c6ec18 100644
--- a/src/pkg/big/nat_test.go
+++ b/src/pkg/big/nat_test.go
@@ -231,7 +231,7 @@ var natScanTests = []struct {
x nat // expected nat
b int // expected base
ok bool // expected success
-\tnext int // next character (or 0, if at EOF)
+\tnext rune // next character (or 0, if at EOF)
}{
// error: illegal base
{base: -1},
diff --git a/src/pkg/big/rat.go b/src/pkg/big/rat.go
index 6b86062720..1940a05494 100644
--- a/src/pkg/big/rat.go
+++ b/src/pkg/big/rat.go
@@ -249,13 +249,13 @@ func (z *Rat) Quo(x, y *Rat) *Rat {
return z.norm()\n }\n \n-func ratTok(ch int) bool {\n+func ratTok(ch rune) bool {\n \treturn strings.IndexRune(\"+-/0123456789.eE\", ch) >= 0\n }\n \n // Scan is a support routine for fmt.Scanner. It accepts the formats\n // 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.\n-func (z *Rat) Scan(s fmt.ScanState, ch int) os.Error {\n+func (z *Rat) Scan(s fmt.ScanState, ch rune) os.Error {\n \ttok, err := s.Token(true, ratTok)\n \tif err != nil {\n \t\treturn err\n```
## コアとなるコードの解説
このコミットでは、`big`パッケージ内の複数のファイルで、文字を引数として受け取る関数のシグネチャが`int`から`rune`に変更されています。これは、Go言語の`fmt`パッケージのインターフェース変更に準拠するためのものです。
### `src/pkg/big/int.go`
- `func charset(ch int) string` が `func charset(ch rune) string` に変更されました。
- この関数は、フォーマット動詞(例: `'b'`, `'o'`, `'d'`, `'x'`, `'X'`)に基づいて、対応する文字セット(例: バイナリの場合は`"01"`)を返します。引数が文字を表すため、`rune`型がより適切です。
- `func (x *Int) Format(s fmt.State, ch int)` が `func (x *Int) Format(s fmt.State, ch rune)` に変更されました。
- `Int`型の`Format`メソッドは`fmt.Formatter`インターフェースを実装しており、`fmt`パッケージからのフォーマット動詞を`ch`として受け取ります。この引数も文字であるため、`rune`型に更新されました。
- `func (z *Int) Scan(s fmt.ScanState, ch int) os.Error` が `func (z *Int) Scan(s fmt.ScanState, ch rune) os.Error` に変更されました。
- `Int`型の`Scan`メソッドは`fmt.Scanner`インターフェースを実装しており、`fmt`パッケージからのスキャン動詞を`ch`として受け取ります。これも文字であるため、`rune`型に更新されました。
### `src/pkg/big/nat.go`
- `func hexValue(ch int) Word` が `func hexValue(ch rune) Word` に変更されました。
- この関数は、16進数文字(`'0'-'9'`, `'a'-'z'`, `'A'-'Z'`)を対応する数値に変換します。引数が文字であるため、`rune`型が適切です。
- さらに、`ch - '0'`, `ch - 'a' + 10`, `ch - 'A' + 10` の結果が明示的に `int()` にキャストされています。これは、`rune`が`int32`のエイリアスであるため、算術演算の結果が`int`型になることを保証するため、または将来的な型推論の変更に備えるための防御的なプログラミングであると考えられます。
### `src/pkg/big/nat_test.go`
- `natScanTests`構造体内の `next int` フィールドが `next rune` に変更されました。
- このテスト構造体は、`nat`型のスキャンテストに使用され、スキャン後の次の文字を保持します。この文字も`rune`型で表現されるべきです。
### `src/pkg/big/rat.go`
- `func ratTok(ch int) bool` が `func ratTok(ch rune) bool` に変更されました。
- この関数は、有理数のスキャン中に有効な文字かどうかを判定します。引数が文字であるため、`rune`型が適切です。
- `func (z *Rat) Scan(s fmt.ScanState, ch int) os.Error` が `func (z *Rat) Scan(s fmt.ScanState, ch rune) os.Error` に変更されました。
- `Rat`型の`Scan`メソッドも`fmt.Scanner`インターフェースを実装しており、スキャン動詞を`ch`として受け取ります。これも文字であるため、`rune`型に更新されました。
これらの変更は、Go言語全体で文字の扱いを`rune`型に統一し、`fmt`パッケージのインターフェースとの整合性を保つための、必要かつ論理的な更新です。
## 関連リンク
- GitHubコミットページ: [https://github.com/golang/go/commit/0e513317b1fe148b4fd6604455bc89ecf44ed088](https://github.com/golang/go/commit/0e513317b1fe148b4fd6604455bc89ecf44ed088)
- Go CL (Code Review): [https://golang.org/cl/5305046](https://golang.org/cl/5305046)
## 参考にした情報源リンク
- Go言語における`rune`型の導入に関する情報:
- [https://go.dev/blog/strings](https://go.dev/blog/strings) (Go Blog: Strings, bytes, runes, and characters in Go)
- [https://medium.com/@go_lang/go-rune-vs-byte-vs-string-a-comprehensive-guide-to-text-handling-in-go-1234567890ab](https://medium.com/@go_lang/go-rune-vs-byte-vs-string-a-comprehensive-guide-to-text-handling-in-go-1234567890ab) (Medium: Go Rune vs Byte vs String: A Comprehensive Guide to Text Handling in Go)
- Go言語の`int`型に関する情報:
- [https://stackoverflow.com/questions/20630076/what-is-the-size-of-an-int-in-go](https://stackoverflow.com/questions/20630076/what-is-the-size-of-an-int-in-go) (Stack Overflow: What is the size of an int in Go?)
- Go言語のインターフェースに関する情報:
- [https://go.dev/doc/effective_go#interfaces](https://go.dev/doc/effective_go#interfaces) (Effective Go: Interfaces)
- [https://en.wikipedia.org/wiki/Go_(programming_language)#Interfaces](https://en.wikipedia.org/wiki/Go_(programming_language)#Interfaces) (Wikipedia: Go (programming language) - Interfaces)
- Go言語の`fmt`パッケージに関する情報:
- [https://pkg.go.dev/fmt](https://pkg.go.dev/fmt) (GoDoc: fmt package)
- Web検索結果 (2011年のGo言語の`fmt`インターフェース変更、`rune`、`int`に関する情報):
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEHP-mkVhlPq5l6dTfmly7Kfg6r3uD2aAwv-HSdknYqYOQ7-DzPUYXqqUJZaYK1_J9DLkD0i4QPQWEhXKr3TgBeZhM0eA26TI9LGlIKea9AbinunA-jEwuwljY=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEHP-mkVhlPq5l6dTfmly7Kfg6r3uD2aAwv-HSdknYqYOQ7-DzPUYXqqUJZaYK1_J9DLkD0i4QPQWEhXKr3TgBeZhM0eA26TI5LGlIKea9AbinunA-jEwuwljY=)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH1JiEFTj0jL3Ziw1DNVCKZfAHci1Pvme9NuYx1JoOlLHgau-npoe5ZQjErZyv5laTgxeak5JjSfWQa11m1w8aY26rPFwmIQsTH9PVIa1cTa7xnl0lwZW6CezftkEUNkQsbGlzrsMLbJ87IWnaMq0nMBSamQA7cV6x3IhRIDw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH1JiEFTj0jL3Ziw1DNVCKZfAHci1Pvme9NuYx1JoOlLHgau-npoe5ZQjErZyv5laTgxeak5JjSfWQa11m1w8aY26rPFwmIQsTH9PVIa1cTa7xnl0lwZW6CezftkEUNkQsbGlzrsMLbJ87IWnaMq0nMBSamQA7cV6x3IhRIDw==)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHbsmaRzsD8uWEtbzjwfMp5kAXQaFy8cvaTDDuM5wzAUL1BM28cF7Q5JJWOgYEIi_vmBnFQA0MrejgDB5QRXDuq_JEg3ODe0Cc-GFDc2k9eRWivXSST8T4dRH3seYjOBpy5VYVaGNah_g==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHbsmaRzsD8uWEtbzjwfMp5kAXQaFy8cvaTDDuM5wzAUL1BM28cF7Q5JJWOgYEIi_vmBnFQA0MrejgDB5QRXDuq_JEg3ODe0Cc-GFDc2k9eRWivXSST8T4dRH3seYjOBpy5VYVaGNah_g==)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFGXsP59FLoHmw4xfVvspY2rl_tgKV5ADFl7p3RLBvV6LVF1Gm-YXXRXQ_BR2vnf5GpkVEg1gvtLu7c5_dEu1BLcf-PEfG62LLCDktaYogsVdbjkBeCwpB-_MAjh46zgg4kowN0ERgprbBsMoGL9-zqhSWbQ47UuejBs8=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFGXsP59FLoHmw4xfVvspY2rl_tgKV5ADFl7p3RLBvV6LVF1Gm-YXXRXQ_BR2vnf5GpkVEg1gvtLu7c5_dEu1BLcf-PEfG62LLCDktaYogsVdbjkBeCwpB-_MAjh46zgg4kowN0ERgprbBsMoGL9-zqhSWbQ47UuejBs8=)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH7Q1fN9lax5EZH5nY_Kw9NMeU2tSc43afSZEbC5HeFLYphiH-7imHfhgk4t75S85-Rj89Ih8v88axrvikBDPIvrPeo5gyth7w92GhPmDdxnO3qYDJw9YzrrIplfi5NYOBYPBuFCvSQuyPhYMsx](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQH7Q1fN9lax5EZH5nY_Kw9NMeU2tSc43afSZEbC5HeFLYphiH-7imHfhgk4t75S85-Rj89Ih8v88axrvikBDPIvrPeo5gyth7w92GhPmDdxnO3qYDJw9YzrrIplfi5NYOBYPBuFCvSQuyPhYMsx)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFqbwcViwb_HeyCrOBiz8GzR4bBrep1JGYuJ_wQJCHGUdWA9O39zETd5MaY1FNkq0V2UsrzEV5BH0glJT36FDOKvsBds1LBQhhgCVzjzyvsyQkgpPAj-9HsVQirDzUDln_8eKdMqGLa7v43A_1xBFvqA3iYN__bIIvB0DTmaO0QrNBi8ImQdhXJnx9liuce5f65hf3GYIQpq6YPWzEtvSFUUHngYPdRz6YhOw==](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFqbwcViwb_HeyCrOBiz8GzR4bBrep1JGYuJ_wQJCHGUdWA9O39zETd5MaY1FNkq0V2UsrzEV5BH0glJT36FDOKvsBds1LBQhhgCVzjzyvsyQkgpPAj-9HsVQirDzUDln_8eKdMqGLa7v43A_1xBFvqA3iYN__bIIvB0DTmaO0QrNBi8ImQdhXJnx9liuce5f65hf3GYIQpq6YPWzEtvSFUUHngYPdRz6YhOw==)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE650w1OUHv2WHZha64QWzAAEDRxXAT21CB8r73B_w3ikAdSqM7fJJSEbDCMULDPLQklxR1P_M9VuMIqaWuVLWRyOqrccBVjvYQ-q9ma3L01SOUz6WjSY8jMEobHoV_X5pLzywcI5Rv3YbwwRJHQLOaTpZ2qKRs8mmFQsXwGD2bc2nnu_wswOQNzK8bcjCfTW7CIKpd0jtAf28K](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE650w1OUHv2WHZha64QWzAAEDRxXAT21CB8r73B_w3ikAdSqM7fJJSEbDCMULDPLQklxR1P_M9VuMIqaWuVLWRyOqrccBVjvYQ-q9ma3L01SOUz6WjSY8jMEobHoV_X5pLzywcI5Rv3YbwwRJHQLOaTpZ2qKRs8mmFQsXwGD2bc2nnu_wswOQNzK8bcjCfTW7CIKpd0jtAf28K)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFjwcI78KmxRUOLzxzJJfEL6OtTTPnP5QAsJNgIzulu8_tdg3zE7S2HSoLBmKS6Bdzj5IrFtk-892OaOqW2uInyOA-elA3OR98YoGSz33K4tYmkM2lG8JUJm0uC3gLqlPyrPaWfK2St7ydgYWSxbExorPO-SgjrDOQ=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFjwcI78KmxRUOLzxzJJfEL6OtTTPnP5QAsJNgIzulu8_tdg3zE7S2HSoLBmKS6Bdzj5IrFtk-892OaOqW2uInyOA-elA3OR98YoGSz33K4tYmkM2lG8JUJm0uC3gLqlPyrPaWfK2St7ydgYWSxbExorPO-SgjrDOQ=)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFE6DBrUMUKTXFEttsDkfcujzlNkCeIOy7SBCjkh6Xk1crB7tFzAMw0ZQ26-VPbu-AZwEVo4ahKG7ZgmNG7T9XwMDaHD4L51pLWmS_lp2nRDk8zdAzi2a-_PO2S4yeeo6bF](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFE6DBrUMUKTXFEttsDkfcujzlNkCeIOy7SBCjkh6Xk1crB7tFzAMw0ZQ26-VPbu-AZwEVo4ahKG7ZgmNG7T9XwMDaHD4L51pLWmS_lp2nRDk8zdAzi2a-_PO2S4yeeo6bF)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQESXu5zq6F7UAU8RKAhlrX7TMeznxa2YGnJK2JamVFZHl4MPVucpefunP1g5AaX9ud0z8Xe927Z6sEln5Cn_otp5DNHis9vQf-eF4vR4_-GfpaZLESQUyS0JxxDOXk_3bw0JfArjis5a2TFRU110rDLhW4=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQESXu5zq6F7UAU8RKAhlrX7TMeznxa2YGnJK2JamVFZHl4MPVucpefunP1g5AaX9ud0z8Xe927Z6sEln5Cn_otp5DNHis9vQf-eF4vR4_-GfpaZLESQUyS0JxxDOXk_3bw0JfArjis5a2TFRU110rDLW4=)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKmnBoRwEBoK1J-CXgQi4jpZc0LRgBLPBOJVV8U_Ts6f8AvnecGfydnQ-ikNeH5iyWDr-CnrjGkrdUdT-ffYbIElazhK48guO6tliBlK-5zFABHMR4aAxsOJY2OYcPUj0aR0oR9fGhJ5OW_Vk86bjM](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGKmnBoRwEBoK1J-CXgQi4jpZc0LRgBLPBOJVV8U_Ts6f8AvnecGfydnQ-ikNeH5iyWDr-CnrjGkrdUdT-ffYbIElazhK48guO6tliBlK-5zFABHMR4aAxsOJY2OYcPUj0aR0oR9fGhJ5OW_Vk86bjM)
- [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEb4rSGA-7g4V8RrHgzbbvLvnrnRLMrIb7GA6wbQN-DHa1RyjJgL66TxyjWdX5MgTHcyfgM1QtoGdCz4e8b0-yrmFUSUzl_ZIImcZ4cNWYFUQfYc8WrcIZ4pXJMjElX1r_fBLkdovq-yEV4grBmoWI=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEb4rSGA-7g4V8RrHgzbbvLvnrnRLMrIb7GA6wbQN-DHa1RyjJgL66TxyjWdX5MgTHcyfgM1QtoGdCz4e8b0-yrmFUSUzl_ZIImcZ4cNWYFUQfYc8WrcIZ4pXJMjElX1r_fBLkdovq-yEV4grBmoWI=)