【Go言語】big.Int.Scan()を使いこなす:入力例とトラブルシューティング

2025-06-01

簡単に言うと、big.Int.Scan()文字列形式の数値を big.Int 型にパース(解析)して代入する ためのメソッドです。

big.Int.Scan() の主な機能

  • エラーハンドリング
    パースに失敗した場合(例えば、不正な形式の数値が入力された場合)はエラーを返します。
  • 基数の自動判別
    入力文字列のプレフィックス(接頭辞)に基づいて、自動的に基数(進数)を判別します。
    • 0x または 0X で始まる場合: 16進数
    • 0o または 0O で始まる場合: 8進数 (Go 1.13以降)
    • 0b または 0B で始まる場合: 2進数 (Go 1.13以降)
    • それ以外の場合: 10進数
  • 入力の読み込み
    fmt.Scanfmt.Sscan などの関数と組み合わせて使用することで、標準入力や文字列から数値を読み込むことができます。
package main

import (
	"fmt"
	"math/big"
	"strings"
)

func main() {
	var i big.Int

	// 1. 標準入力から読み込む例
	// fmt.Print("整数を入力してください: ")
	// _, err := fmt.Scan(&i)
	// if err != nil {
	// 	fmt.Println("エラー:", err)
	// } else {
	// 	fmt.Printf("読み込んだ値: %s\n", i.String())
	// }

	// 2. 文字列から読み込む例 (10進数)
	reader := strings.NewReader("12345678901234567890")
	_, err := fmt.Fscan(reader, &i)
	if err != nil {
		fmt.Println("エラー:", err)
	} else {
		fmt.Printf("文字列から読み込んだ値 (10進数): %s\n", i.String())
	}

	// 3. 文字列から読み込む例 (16進数)
	reader = strings.NewReader("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
	_, err = fmt.Fscan(reader, &i)
	if err != nil {
		fmt.Println("エラー:", err)
	} else {
		fmt.Printf("文字列から読み込んだ値 (16進数): %s\n", i.String())
	}

	// 4. 文字列から読み込む例 (不正な入力)
	reader = strings.NewReader("abc")
	_, err = fmt.Fscan(reader, &i)
	if err != nil {
		fmt.Println("エラー (不正な入力):", err)
	} else {
		fmt.Printf("文字列から読み込んだ値 (不正な入力): %s\n", i.String())
	}
}

big.Int.Scan()fmt.Scanner インターフェースを実装しているため、fmt.Scan()fmt.Sscan()fmt.Fscan() など、fmt.Scanner を引数に取る関数で使用できます。



無効な入力形式 (Invalid Input Format)

エラーの症状
big.Int.Scan() は、数値として解釈できない文字列が入力された場合にエラーを返します。例えば、数字以外の文字が含まれていたり、基数指定(0xなど)が誤っていたりする場合です。

よくあるエラーメッセージの例
strconv.ParseInt: parsing "abc": invalid syntax (実際には fmt.Scan 経由で呼び出されるため、より汎用的なエラーメッセージになることもあります。)

原因

  • 意図しないプレフィックス(例: 10進数のつもりで "0x123" と入力)が付いている。
  • 予期せぬ空白文字や改行文字が入力の先頭または末尾に存在している。
  • 入力文字列に、その基数で許可されない文字が含まれている。

トラブルシューティング

  • SetStringの利用
    big.Int.Scan()fmt.Scanner インターフェースを実装しているため、自動的に基数を判別します。しかし、明示的に基数を指定してパースしたい場合は、big.Int.SetString(s string, base int) を使う方が安全で意図が明確になります。
    i := new(big.Int)
    s := "0xAF" // 16進数としてパースしたい
    _, ok := i.SetString(s, 0) // baseを0にするとScan()と同じく自動判別
    // または
    _, ok := i.SetString(s, 16) // 明示的に16進数と指定
    if !ok {
        fmt.Println("パース失敗")
    }
    
  • 入力ソースの確認
    • 標準入力からの場合、ユーザーが正しい形式で入力しているかを確認します。
    • ファイルやネットワークからの読み込みの場合、データが破損していないか、エンコーディングが正しいかを確認します。
  • エラーハンドリング
    fmt.Scanfmt.Fscan が返す error を必ずチェックし、エラーが発生した場合はユーザーに適切なフィードバックを返すようにします。
  • 入力検証
    big.Int.Scan() を呼び出す前に、入力文字列が有効な数値形式であるかを正規表現などを使って事前に検証することを検討してください。

空の入力 (Empty Input)

エラーの症状
big.Int.Scan() は、入力が空の場合にもエラーを返すことがあります。

原因

  • ファイルから読み込む際に、空行やファイルの終端に達した。
  • 標準入力で何も入力せずにEnterキーを押した。

トラブルシューティング

  • 事前チェック
    bufio.Reader などを使って入力行を先に読み込み、空であるかをチェックしてから big.Int.SetString() を使うことも有効です。
  • io.EOFのチェック
    fmt.Scan などは、入力ストリームの終端に達した場合に io.EOF エラーを返すことがあります。これを適切に処理することで、プログラムが予期せず終了するのを防げます。
    _, err := fmt.Scan(&i)
    if err == io.EOF {
        fmt.Println("入力がありませんでした。")
        // または、デフォルト値を設定するなど
    } else if err != nil {
        fmt.Println("エラー:", err)
    }
    

big.Int の初期化忘れ (big.Int not initialized)

エラーの症状
これは Scan() 自体のエラーというより、Goのポインタレシーバのメソッドを使用する際の一般的な誤りです。big.Int のメソッドは通常ポインタレシーバ *big.Int で定義されています。

よくある間違い

var i big.Int // ポインタではない
fmt.Scan(i)   // これはコンパイルエラーになるか、実行時パニックを引き起こす可能性があります

原因
fmt.Scanfmt.Scanner インターフェースを実装する値(ポインタ)を期待しています。big.Int のメソッドはポインタレシーバで定義されているため、Scan メソッドを呼び出すには *big.Int 型の変数が必要です。

トラブルシューティング

  • ポインタで宣言
    big.Int 型の変数はポインタとして宣言し、new(big.Int) で初期化するか、& 演算子でアドレスを渡します。
    var i big.Int
    // または i := new(big.Int) としても良い
    _, err := fmt.Scan(&i) // &i を渡す
    if err != nil {
        fmt.Println("エラー:", err)
    } else {
        fmt.Printf("読み込んだ値: %s\n", i.String())
    }
    

エラーの症状
データベースから big.Int 型の値を読み込もうとした際に、unsupported Scan, storing driver.Value type X into type *big.Int のようなエラーが発生することがあります。

原因
これは big.Int.Scan() 自体の問題ではなく、データベースドライバーが *big.Int 型を直接サポートしていないために発生します。データベースの数値型(NUMERIC, DECIMAL, BIGINTなど)がGoの big.Int に直接マッピングされない場合、ドライバーは int64float64、または []byte (文字列形式) として値を返そうとします。

  • ドライバーのドキュメント確認
    使用しているデータベースドライバーが big.Int をサポートしているか、特別な設定が必要かを確認します。一部のドライバーは特定のデータ型に対してカスタムスキャンロジックを提供している場合があります。
  • 中間的な型として string または []byte を使用
    データベースから一旦文字列 (string または []byte) として読み込み、その後 big.Int.SetString() を使って big.Int に変換します。これが最も一般的な解決策です。
    var s string
    err := rows.Scan(&s) // データベースから文字列として読み込む
    if err != nil {
        // エラーハンドリング
    }
    
    var bigInt big.Int
    _, ok := bigInt.SetString(s, 10) // 10進数としてパース
    if !ok {
        fmt.Println("SetString 失敗:", s)
    }
    


基本的な使用例:標準入力からの読み込み

最も基本的な使い方です。ユーザーがコンソールから入力した数値を big.Int として読み込みます。

package main

import (
	"fmt"
	"math/big"
	"io" // io.EOF を使うためにインポート
)

func main() {
	var bigInt big.Int // big.Int のポインタをScanに渡すため、&bigInt とします

	fmt.Println("大きな整数を入力してください:")

	// fmt.Scan を使用して標準入力から読み込む
	// fmt.Scan は空白区切りで入力を読み取ります
	n, err := fmt.Scan(&bigInt) // &bigInt を渡すことに注意

	if err != nil {
		if err == io.EOF {
			fmt.Println("入力がありませんでした (EOF)。")
		} else {
			fmt.Printf("入力エラーが発生しました: %v\n", err)
		}
		return
	}

	if n == 0 {
		fmt.Println("何も読み込まれませんでした。")
		return
	}

	fmt.Printf("入力された数値: %s\n", bigInt.String())
	fmt.Printf("型の確認: %T\n", bigInt) // big.Int 型であることがわかります
}

解説

  • エラーチェックは重要です。特に io.EOF は、入力が完全に終了した場合(例えば、ファイルの終端に達した場合)に発生します。
  • fmt.Scan は、読み込んだ要素の数とエラーを返します。
  • fmt.Scan(&bigInt) のように、& を付けて変数のアドレスを渡す必要があります。これは Scan メソッドがポインタレシーバ (*big.Int) を持つためです。
  • var bigInt big.Intbig.Int 型の変数を宣言します。

文字列からの読み込み (strings.Reader と fmt.Fscan)

標準入力だけでなく、io.Reader インターフェースを実装する任意のソースから読み込むことができます。ここでは strings.NewReader を使って文字列から読み込む例を示します。

package main

import (
	"fmt"
	"math/big"
	"strings" // strings.NewReader を使うためにインポート
)

func main() {
	var num big.Int

	// 10進数の文字列
	decimalStr := "987654321098765432109876543210"
	reader1 := strings.NewReader(decimalStr)
	fmt.Printf("文字列 '%s' を読み込み中...\n", decimalStr)
	_, err := fmt.Fscan(reader1, &num)
	if err != nil {
		fmt.Printf("エラー: %v\n", err)
	} else {
		fmt.Printf("読み込んだ値: %s\n", num.String())
	}

	fmt.Println("---")

	// 16進数の文字列 (0x プレフィックス付き)
	hexStr := "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
	reader2 := strings.NewReader(hexStr)
	fmt.Printf("文字列 '%s' を読み込み中...\n", hexStr)
	_, err = fmt.Fscan(reader2, &num) // 同じ big.Int 変数を再利用
	if err != nil {
		fmt.Printf("エラー: %v\n", err)
	} else {
		fmt.Printf("読み込んだ値: %s (10進数表現)\n", num.String())
	}

	fmt.Println("---")

	// 不正な形式の文字列
	invalidStr := "not_a_number"
	reader3 := strings.NewReader(invalidStr)
	fmt.Printf("文字列 '%s' を読み込み中...\n", invalidStr)
	_, err = fmt.Fscan(reader3, &num)
	if err != nil {
		fmt.Printf("エラー (期待通り): %v\n", err) // このエラーは期待通り
	} else {
		fmt.Printf("予期せず読み込んだ値: %s\n", num.String())
	}
}

解説

  • 不正な入力に対してはエラーが返されることを確認できます。
  • big.Int.Scan() は、0x (16進数)、0o (8進数、Go 1.13+)、0b (2進数、Go 1.13+) のプレフィックスを自動的に解釈します。プレフィックスがない場合は10進数と見なされます。
  • fmt.Fscan(reader, &num) は、指定された reader から num に値をスキャンします。
  • strings.NewReader(s) は、与えられた文字列 sio.Reader として扱うためのオブジェクトを作成します。

bufio.Scanner と big.Int.SetString を組み合わせる(より堅牢な方法)

fmt.Scan は空白区切りで読み込みますが、1行全体を読み込みたい場合や、より細かい制御が必要な場合は、bufio.Scanner を使って行を読み込み、その後 big.Int.SetString() でパースする方が良い場合があります。この方法は、Scan() が内部的に行っていることと似ていますが、エラーハンドリングや前処理を柔軟に行えます。

package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	var bigInt big.Int

	fmt.Println("大きな整数を1行ずつ入力してください ('exit' で終了):")

	for scanner.Scan() {
		line := scanner.Text() // 1行全体を文字列として取得
		line = strings.TrimSpace(line) // 前後の空白をトリム

		if line == "exit" {
			fmt.Println("終了します。")
			break
		}

		if line == "" {
			fmt.Println("空の行です。再入力してください。")
			continue
		}

		// big.Int.SetString を使用して文字列からパース
		// base が 0 の場合、Scan() と同じように自動的に基数を判別します
		_, ok := bigInt.SetString(line, 0)
		if !ok {
			fmt.Printf("エラー: '%s' は有効な数値ではありません。再入力してください。\n", line)
			continue
		}

		fmt.Printf("入力された数値: %s\n", bigInt.String())
	}

	if err := scanner.Err(); err != nil {
		fmt.Printf("Scanner エラー: %v\n", err)
	}
}

解説

  • SetString は成功/失敗を示すブール値を返すため、if !ok でエラーハンドリングを行います。
  • bigInt.SetString(line, 0) を使って、文字列 linebig.Int にパースします。第二引数の 0 は、Scan() と同様に、文字列のプレフィックスに基づいて基数を自動判別することを意味します。
  • strings.TrimSpace(line) で、入力文字列の先頭と末尾にある空白文字(スペース、タブ、改行など)を削除します。これにより、入力ミスによるパースエラーを防ぎやすくなります。
  • scanner.Text() で読み込んだ行を文字列として取得します。
  • scanner.Scan() で次の行を読み込みます。
  • bufio.NewScanner(os.Stdin) で標準入力を行単位で読み込むためのスキャナーを作成します。

これは big.Int.Scan() の直接の例ではありませんが、データベースの Scan メソッドで big.Int を扱う際によく遭遇する問題とその解決策です。多くのデータベースドライバは直接 *big.Int をサポートしていないため、中間的に文字列として読み込む必要があります。

package main

import (
	"database/sql"
	"fmt"
	"math/big"
	_ "github.com/mattn/go-sqlite3" // 例としてSQLite3ドライバを使用
)

// これは実際にデータベースに接続するダミー関数です。
// 実際のアプリケーションでは、適切なデータベース設定とクエリを使用してください。
func simulateDBScan(value string) (*big.Int, error) {
	// 実際には sql.DB.QueryRow().Scan(&dbValue) などが行われます
	// ここでは文字列として受け取ったものをそのまま利用します

	var bigInt big.Int
	_, ok := bigInt.SetString(value, 10) // 10進数としてパースする例
	if !ok {
		return nil, fmt.Errorf("データベースからの値 '%s' のパースに失敗しました", value)
	}
	return &bigInt, nil
}

func main() {
	// SQLite3 データベースをインメモリで作成 (テスト用)
	db, err := sql.Open("sqlite3", ":memory:")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	// テーブル作成とデータの挿入
	_, err = db.Exec(`CREATE TABLE numbers (id INTEGER PRIMARY KEY, large_num TEXT);`)
	if err != nil {
		panic(err)
	}

	largeNumStr := "1234567890123456789012345678901234567890"
	_, err = db.Exec(`INSERT INTO numbers (large_num) VALUES (?);`, largeNumStr)
	if err != nil {
		panic(err)
	}

	// データベースから読み込む
	var storedLargeNumStr string // 一旦文字列として受け取る
	var storedID int
	
	row := db.QueryRow(`SELECT id, large_num FROM numbers WHERE id = 1;`)
	err = row.Scan(&storedID, &storedLargeNumStr) // データベースドライバーは文字列として返す
	if err != nil {
		if err == sql.ErrNoRows {
			fmt.Println("データが見つかりません。")
		} else {
			fmt.Printf("DBスキャンエラー: %v\n", err)
		}
		return
	}

	// 読み込んだ文字列を big.Int に変換
	var bigIntFromDB big.Int
	_, ok := bigIntFromDB.SetString(storedLargeNumStr, 10) // 10進数としてパース
	if !ok {
		fmt.Printf("DBからの文字列 '%s' の big.Int への変換に失敗しました。\n", storedLargeNumStr)
		return
	}

	fmt.Printf("DBから読み込んだID: %d\n", storedID)
	fmt.Printf("DBから読み込んだ大きな数値: %s\n", bigIntFromDB.String())
}
  • この例では、go-sqlite3 ドライバーを使用しています。実際のデータベース(PostgreSQL, MySQLなど)でも同様のアプローチが一般的です。
  • 解決策
    データベースの数値列を文字列 (TEXT または VARCHAR) として定義し、Go側で string または []byte として読み込みます。その後、big.Int.SetString() を使って big.Int に変換します。
  • データベースドライバーは big.Int を直接サポートしないことが多いため、sql.Rows.Scansql.Row.Scan メソッドに *big.Int を渡してもエラーになります。


big.Int.Scan() の代替方法

主な代替方法は、big.Int 型の以下のメソッドを利用することです。

  1. big.Int.SetString(s string, base int) (*big.Int, bool)
  2. big.Int.SetBytes(buf []byte) *big.Int (または big.Int.SetBytes([]byte) のバリアント)
  3. big.Int.SetUint64(x uint64) *big.Int / big.Int.SetInt64(x int64) *big.Int

これらのメソッドは、それぞれ異なる種類の入力から big.Int の値を設定するために使われます。

big.Int.SetString(s string, base int)

これが big.Int.Scan() の最も直接的で一般的な代替方法です。特に、すでに文字列として数値を持っている場合に非常に便利です。

特徴

  • エラー処理の容易さ
    エラーメッセージが Scan() よりも具体的になる傾向があります。
  • 成功/失敗の明示
    bool 値を返すため、パースが成功したか失敗したかを明確に判断できます。
  • 明示的な基数指定
    base 引数で明示的に基数(2進数、8進数、10進数、16進数など)を指定できます。
    • base0 の場合、big.Int.Scan() と同様に、文字列のプレフィックス (0x, 0o, 0b) に基づいて自動的に基数を判別します。プレフィックスがない場合は10進数と見なします。
    • base2 から 62 の範囲で指定された場合、その基数で文字列を解釈します。

使用例

package main

import (
	"fmt"
	"math/big"
)

func main() {
	var i big.Int

	// 1. 10進数の文字列から設定
	decimalStr := "123456789012345678901234567890"
	fmt.Printf("10進数 '%s' を SetString...\n", decimalStr)
	_, ok := i.SetString(decimalStr, 10) // 10進数として明示的に指定
	if !ok {
		fmt.Printf("エラー: 10進数のパースに失敗しました。\n")
	} else {
		fmt.Printf("結果: %s\n", i.String())
	}

	fmt.Println("---")

	// 2. 16進数の文字列から設定 (0x プレフィックスなし)
	hexStrNoPrefix := "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
	fmt.Printf("16進数 '%s' を SetString...\n", hexStrNoPrefix)
	_, ok = i.SetString(hexStrNoPrefix, 16) // 16進数として明示的に指定
	if !ok {
		fmt.Printf("エラー: 16進数のパースに失敗しました。\n")
	} else {
		fmt.Printf("結果: %s\n", i.String())
	}

	fmt.Println("---")

	// 3. プレフィックス付きで自動判別 (base = 0)
	autoDetectHexStr := "0xABCDEF1234567890"
	fmt.Printf("自動判別 '%s' (base=0) を SetString...\n", autoDetectHexStr)
	_, ok = i.SetString(autoDetectHexStr, 0) // 自動判別
	if !ok {
		fmt.Printf("エラー: 自動判別のパースに失敗しました。\n")
	} else {
		fmt.Printf("結果: %s\n", i.String())
	}

	fmt.Println("---")

	// 4. 不正な文字列の例
	invalidStr := "hello_world"
	fmt.Printf("不正な文字列 '%s' を SetString...\n", invalidStr)
	_, ok = i.SetString(invalidStr, 10)
	if !ok {
		fmt.Printf("エラー: '%s' は有効な数値ではありません。(期待通り)\n", invalidStr)
	} else {
		fmt.Printf("結果: %s\n", i.String())
	}
}

SetString を使うべきシナリオ

  • fmt.Scan のような「空白区切り」ではなく、特定の文字列全体をパースしたい場合。
  • より厳密に基数を指定したい場合。
  • ネットワーク経由で文字列として送られてきた数値をパースする場合。
  • 設定ファイルやコマンドライン引数で受け取った数値が文字列形式の場合。
  • データベースから TEXT 型として読み込んだ値を big.Int に変換したい場合。

big.Int.SetBytes(buf []byte)

このメソッドは、バイトスライスとして表現された大きな数値big.Int に設定するために使用されます。通常、ネットワークプロトコルやファイルフォーマットで数値をバイト列として扱う場合に非常に有用です。

特徴

  • 符号なし整数として扱われます(負の値を直接設定することはできません。別途符号を扱う必要があります)。
  • buf はビッグエンディアン形式のバイト列として解釈されます。

使用例

package main

import (
	"fmt"
	"math/big"
	"encoding/binary" // バイト列の変換に便利
)

func main() {
	var i big.Int

	// 1. シンプルなバイト列 (10進数の 256)
	// [1, 0] はビッグエンディアンで 256
	bytes1 := []byte{1, 0}
	fmt.Printf("バイト列 %v を SetBytes...\n", bytes1)
	i.SetBytes(bytes1)
	fmt.Printf("結果: %s\n", i.String()) // 256

	fmt.Println("---")

	// 2. より大きなバイト列 (例: 64ビット整数をビッグエンディアンで)
	var largeUint64 uint64 = 12345678901234567890 // uint64 の最大に近い値
	buf := make([]byte, 8)
	binary.BigEndian.PutUint64(buf, largeUint64) // uint64 をビッグエンディアンバイト列に変換

	fmt.Printf("バイト列 %v (uint64 %d) を SetBytes...\n", buf, largeUint64)
	i.SetBytes(buf)
	fmt.Printf("結果: %s\n", i.String())

	fmt.Println("---")

	// 3. SetString で得られたバイト列を再度 SetBytes
	// i.Bytes() はビッグエンディアンのバイト列を返す
	originalBigInt := new(big.Int)
	originalBigInt.SetString("987654321098765432109876543210", 10)
	
	bytesFromBigInt := originalBigInt.Bytes()
	fmt.Printf("元々の big.Int: %s\n", originalBigInt.String())
	fmt.Printf("そのバイト列: %v\n", bytesFromBigInt)

	var newBigInt big.Int
	newBigInt.SetBytes(bytesFromBigInt)
	fmt.Printf("バイト列から SetBytes した結果: %s\n", newBigInt.String())
}

SetBytes を使うべきシナリオ

  • 既存の big.IntBytes() メソッドで取得したバイト列を復元する場合。
  • バイナリファイルや特定のプロトコルから数値データを読み込む場合。
  • 暗号化処理やハッシュ計算など、バイトレベルで数値を扱う必要がある場合。

これらのメソッドは、Goの標準の組み込み型である uint64int64 の値を big.Int に変換するために使用されます。

特徴

  • uint64int64 の範囲内の数値であれば、常に正確に変換されます。
  • 非常にシンプルで直接的な変換です。

使用例

package main

import (
	"fmt"
	"math/big"
)

func main() {
	var i big.Int

	// 1. uint64 から設定
	var uVal uint64 = 18446744073709551615 // uint64 の最大値
	fmt.Printf("uint64 %d を SetUint64...\n", uVal)
	i.SetUint64(uVal)
	fmt.Printf("結果: %s\n", i.String())

	fmt.Println("---")

	// 2. int64 から設定
	var iVal int64 = -9223372036854775808 // int64 の最小値
	fmt.Printf("int64 %d を SetInt64...\n", iVal)
	i.SetInt64(iVal)
	fmt.Printf("結果: %s\n", i.String())
}
  • APIの引数や戻り値が uint64int64 であるが、内部で big.Int として処理する必要がある場合。
  • Goの組み込み整数型で計算された結果を、さらに大きな範囲で扱いたい場合。
  • big.Int.SetUint64(x uint64) / big.Int.SetInt64(x int64)

    • Goの組み込み整数型から big.Int への直接変換が必要な場合。
    • 通常、big.Int の計算の開始点として使われることが多い。
  • big.Int.SetBytes(buf []byte)

    • バイト列から数値を再構築したい場合に特化。
    • バイナリデータ処理や暗号化関連のタスクで必要となる。
  • big.Int.SetString(s string, base int)

    • 最も一般的な代替方法。
    • 文字列として数値が手元にある場合に、最も柔軟で信頼性の高い方法。
    • 明示的な基数指定や、成功/失敗の明確な判定が必要な場合に最適。
    • データベースからの読み込みや、設定ファイルのパースなど、様々なIOで役立つ。
  • big.Int.Scan()

    • fmt.Scan のような高レベルな入力関数と連携して、スペース区切りの入力(主に標準入力や簡単なファイル入力)から自動的に基数を判別して読み込みたい場合に便利。
    • しかし、エラー処理や入力の柔軟性では SetString に劣る場合がある。