序章

Goでは、データ型を使用して特定の種類のデータを分類し、その種類に割り当てることができる値と、その種類に対して実行できる操作を決定します。 プログラミング時には、値を別の方法で操作するために、型間で値を変換する必要がある場合があります。 たとえば、数値を文字列と連結したり、整数値として初期化された数値の小数点以下の桁数を表す必要がある場合があります。 ユーザーが生成したデータには、数字で構成されている場合でも、文字列データ型が自動的に割り当てられることがよくあります。 この入力で数学演算を実行するには、文字列を数値データ型に変換する必要があります。

Goは静的に型付けされた言語であるため、データ型は値ではなく変数にバインドされます。 つまり、変数をintとして定義した場合、それはintのみになります。 変数のデータ型を変換せずにstringを割り当てることはできません。 Goのデータ型の静的な性質により、データ型を変換する方法を学ぶことがさらに重要になります。

このチュートリアルでは、数値と文字列の変換について説明し、さまざまなユースケースに慣れるための例を示します。

数値タイプの変換

Goにはいくつかの数値タイプから選択できます。 主に、整数浮動小数点数の2つの一般的なタイプに分類されます。

数値タイプ間で変換したい状況はたくさんあります。 異なるサイズの数値タイプ間で変換すると、特定の種類のシステムアーキテクチャのパフォーマンスを最適化するのに役立ちます。 コードの別の部分からの整数があり、それを除算したい場合は、演算の精度を維持するために整数を浮動小数点数に変換することをお勧めします。 さらに、期間の操作には通常、整数変換が含まれます。 これらの状況に対処するために、Goにはほとんどの数値型に型変換が組み込まれています。

整数型間の変換

Goには、選択できる整数データ型が多数あります。 どちらを使用するかは、通常、パフォーマンスに関するものです。 ただし、ある整数型から別の整数型に変換する必要がある場合があります。 たとえば、Goはintとして数値を自動的に生成することがありますが、これは入力値と一致しない場合があります。 入力値がint64の場合、データ型を一致するように変換するまで、intint64の数値を同じ数式で使用することはできません。

int8があり、それをint32に変換する必要があるとします。 これを行うには、int32()型変換でラップします。

var index int8 = 15

var bigIndex int32

bigIndex = int32(index)

fmt.Println(bigIndex)
Output
15

このコードブロックは、indexint8データ型として定義し、bigIndexint32データ型として定義します。 indexの値をbigIndexに格納するために、データ型をint32に変換します。 これは、int32()変換をindex変数にラップすることによって行われます。

データ型を確認するには、fmt.Printfステートメントと%T動詞を次の構文で使用できます。

fmt.Printf("index data type:    %T\n", index)
fmt.Printf("bigIndex data type: %T\n", bigIndex)
Output
index data type: int8 bigIndex data type: int32

これは%T動詞を使用するため、printステートメントは変数の実際の値ではなく、変数の型を出力します。 このようにして、変換されたデータ型を確認できます。

大きいビットサイズの整数から小さいビットサイズの整数に変換することもできます。

var big int64 = 64

var little int8

little = int8(big)

fmt.Println(little)
Output
64

整数を変換する場合、データ型とラップアラウンドの最大値を超える可能性があることに注意してください。

var big int64 = 129
var little = int8(big)
fmt.Println(little)
Output
-127

値が小さすぎて保持できないデータ型に変換されると、ラップアラウンドが発生します。 前の例では、8ビットデータ型int8には、64ビット変数bigを保持するための十分なスペースがありませんでした。 大きな数値のデータ型から小さな数値のデータ型に変換するときは、誤ってデータを切り捨てないように常に注意する必要があります。

整数から浮動小数点数への変換

Goで整数をfloatに変換することは、ある整数型を別の型に変換することに似ています。 組み込み型変換を使用するには、変換する整数をfloat64()またはfloat32()でラップします。

var x int64 = 57

var y float64 = float64(x)

fmt.Printf("%.2f\n", y)
Output
57.00

このコードは、タイプint64の変数xを宣言し、その値を57に初期化します。

var x int64 = 57

float64()変換をxにラップすると、57の値が57.00の浮動小数点値に変換されます。

var y float64 = float64(x)

%.2f印刷動詞は、fmt.Printfに小数点以下2桁で浮動小数点数をフォーマットするように指示します。

このプロセスを変数で使用することもできます。 次のコードは、f57と等しいことを宣言し、新しいフロートを出力します。

var f float64 = 57
fmt.Printf("%.2f\n", f)
Output
57.00

float32()またはfloat64()のいずれかを使用すると、整数を浮動小数点数に変換できます。 次に、浮動小数点数を整数に変換する方法を学習します。

フロートを整数に変換する

Goはfloatを整数に変換できますが、プログラムはfloatの精度を失います。

int()またはそのアーキテクチャに依存しないデータ型の1つでフロートをラップすると、ある整数型から別の整数型に変換するために使用した場合と同様に機能します。 括弧内に浮動小数点数を追加して、整数に変換できます。

var f float64 = 390.8
var i int = int(f)

fmt.Printf("f = %.2f\n", f)
fmt.Printf("i = %d\n", i)
Output
f = 390.80 i = 390

この構文は、float 390.8を整数390に変換し、小数点以下を削除します。

これを変数で使用することもできます。 次のコードは、b125.0に等しいことを宣言し、c390.8に等しいことを宣言し、それらを整数として出力します。 短い変数宣言(:=)は、構文を短縮します。

b := 125.0
c := 390.8

fmt.Println(int(b))
fmt.Println(int(c))
Output
125 390

int()タイプで浮動小数点数を整数に変換する場合、Goは浮動小数点数の小数と残りの数値を切り捨てて整数を作成します。 390.8を391に切り上げたい場合でも、Goはint()タイプではこれを行わないことに注意してください。 代わりに、小数点が削除されます。

除算によって変換された数値

Goで整数型を除算すると、結果も整数型になり、モジュラスまたは余りが削除されます。

a := 5 / 2
fmt.Println(a)
Output
2

除算するときに、数値タイプのいずれかがfloatである場合、すべてのタイプが自動的にfloatとして宣言されます。

	a := 5.0 / 2
	fmt.Println(a)
Output
2.5

これにより、浮動小数点数5.0が整数2で除算され、答え2.5は小数点以下の精度を保持する浮動小数点数になります。

このセクションでは、さまざまなサイズの整数や浮動小数点数など、さまざまな数値データ型間で変換しました。 次に、数値と文字列を変換する方法を学習します。

文字列による変換

文字列は、1つ以上の文字(文字、数字、または記号)のシーケンスです。 文字列はコンピュータプログラムのデータの一般的な形式であり、特にユーザー生成データを取り込む場合は、文字列を数値に変換したり、数値を文字列に変換したりする必要がある場合があります。

数値を文字列に変換する

Go標準ライブラリのstrconvパッケージのstrconv.Itoaメソッドを使用して、数値を文字列に変換できます。 メソッドの括弧に数値または変数を渡すと、その数値は文字列値に変換されます。

まず、整数の変換を見てみましょう。 整数12を文字列値に変換するには、12strconv.Itoaメソッドに渡すことができます。

package main

import (
	"fmt"
	"strconv"
)

func main() {
	a := strconv.Itoa(12)
	fmt.Printf("%q\n", a)
}

このプログラムを実行すると、次の出力が表示されます。

Output
"12"

数値12を囲む引用符は、数値が整数ではなく文字列値になったことを示します。

:=代入演算子を使用して、aという名前の新しい変数を宣言し、strconv.Itoa()関数から返された値を代入しました。 この場合、変数に値12を割り当てました。 また、fmt.Printf関数で%q動詞を使用しました。これは、提供された文字列を引用するように関数に指示します。

変数を使用すると、整数を文字列に変換することがどれほど実用的であるかを理解し始めることができます。 ユーザーの毎日のプログラミングの進捗状況を追跡し、ユーザーが一度に書き込むコードの行数を入力しているとします。 このフィードバックをユーザーに表示し、文字列と整数の値を同時に出力します。

package main

import (
	"fmt"
)

func main() {
	user := "Sammy"
	lines := 50

	fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
}

このコードを実行すると、次のエラーが発生します。

Output
invalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int)

Goでは文字列と整数を連結できないため、変数linesを文字列値に変換する必要があります。

package main

import (
	"fmt"
	"strconv"
)

func main() {
	user := "Sammy"
	lines := 50

	fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.")
}

これで、コードを実行すると、ユーザーの進捗状況を祝福する次の出力が表示されます。

Output
Congratulations, Sammy! You just wrote 50 lines of code.

整数から文字列ではなく、浮動小数点数を文字列に変換する場合は、同様の手順と形式に従います。 fmt.Sprintメソッドにfloatを渡すと、Go標準ライブラリのfmtパッケージから、floatの文字列値が返されます。 float値自体または変数のいずれかを使用できます。

package main

import (
	"fmt"
)

func main() {
	fmt.Println(fmt.Sprint(421.034))

	f := 5524.53
	fmt.Println(fmt.Sprint(f))
}
Output
421.034 5524.53

文字列と連結することで、それが正しいことを確認するためにテストできます。

package main

import (
	"fmt"
)

func main() {
	f := 5524.53
	fmt.Println("Sammy has " + fmt.Sprint(f) + " points.")
}
Output
Sammy has 5524.53 points.

連結はエラーなしで実行されたため、floatが適切に文字列に変換されたことを確認できます。

文字列を数値に変換する

Go標準ライブラリのstrconvパッケージを使用して、文字列を数値に変換できます。 strconvパッケージには、整数型と浮動小数点型の両方を変換する関数があります。 これは、ユーザーからの入力を受け入れる場合の非常に一般的な操作です。 たとえば、ある人の年齢を尋ねるプログラムがある場合、その人が応答を入力すると、stringとしてキャプチャされます。 次に、それをintに変換して、計算を行う必要があります。

文字列に小数点以下の桁数がない場合は、strconv.Atoi関数を使用して文字列を整数に変換することをお勧めします。 数値を浮動小数点数として使用することがわかっている場合は、strconv.ParseFloatを使用します。

毎日書かれたコード行を追跡しているユーザーSammyの例を使用してみましょう。 これらの値を数学で操作して、ユーザーにより興味深いフィードバックを提供することもできますが、これらの値は現在、文字列に格納されています。

package main

import (
	"fmt"
)

func main() {
	lines_yesterday := "50"
	lines_today := "108"

	lines_more := lines_today - lines_yesterday

	fmt.Println(lines_more)
}
Output
invalid operation: lines_today - lines_yesterday (operator - not defined on string)

2つの数値が文字列に格納されていたため、エラーが発生しました。 減算用のオペランド-は、2つの文字列値の有効なオペランドではありません。

文字列を整数に変換するstrconv.Atoi()メソッドを含めるようにコードを変更します。これにより、元々文字列であった値を使用して計算を行うことができます。 文字列を整数に変換すると失敗する可能性があるため、エラーがないかどうかを確認する必要があります。 ifステートメントを使用して、変換が成功したかどうかを確認できます。

package main

import (
	"fmt"
	"log"
	"strconv"
)

func main() {
	lines_yesterday := "50"
	lines_today := "108"

	yesterday, err := strconv.Atoi(lines_yesterday)
	if err != nil {
		log.Fatal(err)
	}

	today, err := strconv.Atoi(lines_today)
	if err != nil {
		log.Fatal(err)
	}
	lines_more := today - yesterday

	fmt.Println(lines_more)
}

文字列が数値でない可能性があるため、strconv.Atoi()メソッドは、変換された型と潜在的なエラーの両方を返します。 lines_yesterdayからstrconv.Atoi関数を使用して変換する場合は、errの戻り値をチェックして、値が変換されたことを確認する必要があります。 errnilでない場合は、strconv.Atoiが文字列値を整数に正常に変換できなかったことを意味します。 この例では、ifステートメントを使用してエラーをチェックし、エラーが返された場合は、log.Fatalを使用してエラーをログに記録してプログラムを終了しました。

上記のコードを実行すると、次のようになります。

Output
58

次に、数値ではない文字列を変換してみます。

package main

import (
	"fmt"
	"strconv"
)

func main() {
	a := "not a number"
	b, err := strconv.Atoi(a)
	fmt.Println(b)
	fmt.Println(err)
}

次のエラーが発生します。

Output
0 strconv.Atoi: parsing "not a number": invalid syntax

bが宣言されたが、strconv.Atoiが変換に失敗したため、bに値が割り当てられることはありませんでした。 bの値が0であることに注意してください。 これは、Goにはデフォルト値があり、Goではゼロ値と呼ばれるためです。 strconv.Atoiは、文字列の変換にも失敗した理由を説明するエラーを提供します。

文字列とバイトの変換

Goの文字列は、バイトのスライスとして格納されます。 Goでは、[]byte()string()の対応する変換でラップすることにより、バイトのスライスと文字列の間で変換できます。

package main

import (
	"fmt"
)

func main() {
	a := "my string"

	b := []byte(a)

	c := string(b)

	fmt.Println(a)

	fmt.Println(b)

	fmt.Println(c)
}

ここでは、文字列値をaに格納し、それをバイトのスライスbに変換してから、バイトのスライスをcとして文字列に変換し直しました。 次に、ab、およびcを画面に印刷します。

Output
my string [109 121 32 115 116 114 105 110 103] my string

出力の最初の行は、元の文字列my stringです。 印刷される2行目は、元の文字列を構成するバイトスライスです。 3行目は、バイトスライスを安全に文字列に変換して出力できることを示しています。

結論

このGoチュートリアルでは、主に組み込みメソッドを使用して、いくつかの重要なネイティブデータ型を他のデータ型に変換する方法を示しました。 Goでデータ型を変換できると、ユーザー入力を受け入れたり、さまざまな数値型で計算を行ったりすることができます。 後で、Goを使用して、データベースやAPIなどのさまざまなソースからのデータを受け入れるプログラムを作成する場合は、これらの変換方法を使用して、データを確実に処理できるようにします。 また、データをより小さなデータ型に変換することで、ストレージを最適化することもできます。

Goのデータ型の詳細な分析が必要な場合は、Goのデータ型についての記事を確認してください。