Goの計算における「invalid operation: mismatched types」の修正

beginner🔷 Go2026-05-27| Go (全バージョン), Linux/macOS/Windows

Error Message

invalid operation: x + y (mismatched types int and int64)
#go##キャスト#型不一致

背景

最近、ファイルアップロードを追跡する Go スクリプトを書いていた時に壁にぶつかりました。読み込んだ 4,096 バイトと合計ファイルサイズの 2.5 GB を比較しようとしていました。Python や JavaScript の経験から、両方の値が明らかに整数なので、コンパイラが「うまくやってくれる」だろうと期待していました。しかし、ビルドは型不一致エラーですぐにクラッシュしました。

Go の型システムは妥協がありません。intint64 のように、一見同じに見える数値型の間であっても、暗黙の型変換(強制)を行うことを拒否します。これらの変数を加算、減算、または比較しようとすると、コンパイラが拒絶反応を示します:

invalid operation: x + y (mismatched types int and int64)

デバッグプロセス

このエラーは通常、次のようなコードスニペットで発生します:

package main

import (
	"fmt"
	"os"
)

func main() {
	var count int = 10
	fileInfo, _ := os.Stat("data.csv")
	size := fileInfo.Size() // これは int64 を返します

	// ここでビルドが失敗します
	if count < size {
		fmt.Println("処理中...")
	}
}

内部で何が起きているかを確認するには、fmt.Printf%T 動詞を使用します。特定のライブラリ関数が何を返しているか確信が持てない時、これは救世主となります:

fmt.Printf("count の型: %T\n", count)
fmt.Printf("size の型: %T\n", size)

出力により競合が確認されます:

  • count は標準の int です
  • sizeint64 です

解決策

Go は自動で橋渡しをしてくれないため、手動で型を合わせる必要があります。安全性の要件に応じて、主に 2 つの戦略があります。

オプション 1:小さい方の型を int64 にキャストする(推奨)

ほとんどの場合、これが最善の策です。標準の intint64 に変換するのは、ターゲットのコンテナの方が大きいため安全です。オーバーフローのバグが発生するリスクはありません。

if int64(count) < size {
	fmt.Println("int64 キャストで修正済み")
}

オプション 2:int64 を int にキャストする

これは控えめに使用してください。64 ビットシステムでは int は 64 ビット幅ですが、32 ビットシステムでは 32 ビットしかありません。巨大な int64 のファイルサイズ(5 GB など)を 32 ビットの int にキャストすると、値が切り捨てられます。これにより、追跡が非常に困難なロジックバグが発生します。

if count < int(size) {
	fmt.Println("int キャストで修正済み")
}

定数のロジック

countint64 であっても、count < 100 は問題なくコンパイルできることに気づくかもしれません。これは、Go の型のない定数がコンテキストを認識するためです。定数は比較対象の変数の型を採用します。エラーが発生するのは、演算の両側がすでに特定の「型付き」変数として固定されている場合のみです。

検証

修正を検証するため、ロジックを更新して go run main.go を実行しました。型が一致していれば、コンパイラは沈黙し、バイナリが実行されます。また、浮動小数点演算が期待通りに機能することを確認するため、簡単なパーセンテージチェックを追加しました。

// 最終的な検証済みコード
package main

import "fmt"

func main() {
	var processed int = 500
	var total int64 = 1024

	// 混合計算には明示的なキャストを使用する
	percentage := float64(processed) / float64(total) * 100

	fmt.Printf("進捗: %.2f%%\n", percentage)
	
	if int64(processed) != total {
		fmt.Println("ステータス: 未完了")
	}
}

学んだ教訓

  • 厳格さは安全性に直結する: 明示的なキャストを強制することで、Go は C++ や JavaScript の開発者を悩ませる静かなオーバーフローバグを防ぎます。
  • int64 に標準化する: ファイルサイズ、データベース ID、またはタイムスタンプを扱う際、煩わしいキャストを最小限に抑えるために、現在はグローバルで int64 を使用するようにしています。
  • 戻り値の型に注意する: len() のような標準関数は int を返しますが、os.FileInfo.Size()int64 を返します。この違いを念頭に置くことで、ビルドエラーを未然に防ぐことができます。

Related Error Notes