変数は、習得するための重要なプログラミング概念です。 これらは、プログラムで使用している値を表す記号です。

このチュートリアルでは、作成するGoプログラム内でそれらを使用するためのいくつかの変数の基本とベストプラクティスについて説明します。

変数を理解する

技術用語では、変数は、シンボリック名または識別子に関連付けられた値に保管場所を割り当てています。 変数名を使用して、コンピュータープログラム内に格納されている値を参照します。

変数は、値に結び付ける名前が付いたラベルと考えることができます。

Variables in Go

整数1032049348があり、長い数値を何度も何度も再入力するのではなく、変数に格納したいとします。 これを実現するために、変数iのように、覚えやすい名前を使用できます。 変数に値を格納するには、次の構文を使用します。

i := 1032049348

この変数は、値に関連付けられているラベルのように考えることができます。

Go Variable Example

ラベルには変数名iが記述されており、整数値1032049348に関連付けられています。

フレーズi := 1032049348は、いくつかの部分で構成される宣言および割り当てステートメントです。

  • 変数名(i
  • 短い変数宣言の割り当て(:=
  • 変数名に関連付けられている値(1032049348
  • Goによって推測されるデータ型(int

次のセクションで、タイプを明示的に設定する方法については後で説明します。

これらの部分が一緒になって、変数iを整数1032049348の値に等しく設定するステートメントを構成します。

変数を値に設定するとすぐに、初期化するか、その変数を作成します。 これが完了すると、値の代わりに変数を使用できるようになります。

i1032049348の値と等しく設定したら、整数の代わりにiを使用できるので、印刷してみましょう。

package main

import "fmt"

func main() {
	i := 1032049348
	fmt.Println(i)
}
Output
1032049348

また、変数を使用してすばやく簡単に計算を行うこともできます。 i := 1032049348を使用すると、次の構文で整数値813を減算できます。

fmt.Println(i - 813)
Output
1032048535

この例では、Goが計算を行い、変数iから813を減算して、合計1032048535を返します。

数学と言えば、変数は数学の方程式の結果と等しく設定できます。 2つの数値を足し合わせて、その合計の値を変数xに格納することもできます。

x := 76 + 145

この例が代数に似ていることに気づいたかもしれません。 数式や数式内の数値や数量を表すために文字やその他の記号を使用するのと同じように、変数はデータ型の値を表す記号名です。 Go構文を正しくするには、変数が方程式の左側にあることを確認する必要があります。

先に進んでxを印刷しましょう:

package main

import "fmt"

func main() {
	x := 76 + 145
	fmt.Println(x)
}
Output
221

変数x76145の合計に等しく設定されたため、Goは値221を返しました。

変数は、整数だけでなく、任意のデータ型を表すことができます。

s := "Hello, World!"
f := 45.06
b := 5 > 9 // A Boolean value will return either true or false
array := [4]string{"item_1", "item_2", "item_3", "item_4"}
slice := []string{"one", "two", "three"}
m := map[string]string{"letter": "g", "number": "seven", "symbol": "&"}

これらの変数のいずれかを出力すると、Goはその変数と同等のものを返します。 文字列sliceデータ型の代入ステートメントを操作してみましょう。

package main

import "fmt"

func main() {
	slice := []string{"one", "two", "three"}
	fmt.Println(slice)
}
Output
[one two three]

[]string{"one", "two", "three"}のスライス値を変数sliceに割り当て、fmt.Println関数を使用して、sliceを呼び出してその値を出力しました。

変数は、指定された値を受け入れるコンピューター内のメモリの小さな領域を切り分けて、その領域に関連付けることで機能します。

変数の宣言

Goでは、変数を宣言する方法がいくつかあり、場合によっては、まったく同じ変数と値を宣言する方法が複数あります。

初期化せずに、データ型intiという変数を宣言できます。 これは、値を入れるスペースを宣言しますが、初期値は与えないことを意味します。

var i int

これにより、データ型intiとして宣言された変数が作成されます。

次の例のように、equal(=)演算子を使用して値を初期化できます。

var i int = 1

Goでは、これらの形式の宣言は両方ともlong変数宣言と呼ばれます。

短い変数宣言を使用することもできます。

i := 1

この場合、iという変数と、intのデータ型があります。 データ型を指定しない場合、Goはデータ型を推測します。

変数を宣言する3つの方法で、Goコミュニティは次のイディオムを採用しています。

  • 変数を初期化しない場合は、長い形式var i intのみを使用してください。

  • 宣言および初期化するときは、短い形式i := 1を使用してください。

  • Goでデータ型を推測したくないが、短い変数宣言を使用したい場合は、次の構文を使用して、値を目的の型でラップできます。

i := int64(1)

値を初期化するときに長い変数宣言フォームを使用することは、Goでは慣用的なものとは見なされません。

var i int = 1

他の人があなたのプログラムをシームレスに読めるように、Goコミュニティが通常どのように変数を宣言するかに従うのは良い習慣です。

ゼロ値

すべての組み込み型の値はゼロです。 割り当てられた変数は、値が割り当てられていない場合でも使用できます。 次のタイプのゼロ値を確認できます。

package main

import "fmt"

func main() {
	var a int
	var b string
	var c float64
	var d bool

	fmt.Printf("var a %T = %+v\n", a, a)
	fmt.Printf("var b %T = %q\n", b, b)
	fmt.Printf("var c %T = %+v\n", c, c)
	fmt.Printf("var d %T = %+v\n\n", d, d)
}
Output
var a int = 0 var b string = "" var c float64 = 0 var d bool = false

fmt.Printfステートメントで%T動詞を使用しました。 これは、変数のdata typeを出力するように関数に指示します。

Goでは、すべての値にzero値があるため、他の言語のようにundefined値を持つことはできません。 たとえば、一部の言語の boolean は、undefinedtrue、またはfalseであり、three状態を変数。 Goでは、ブール値に対してtwoを超える状態を設定することはできません。

変数の命名:ルールとスタイル

変数の命名は非常に柔軟ですが、覚えておくべきいくつかのルールがあります。

  • 変数名は1語のみにする必要があります(スペースを入れない場合など)。
  • 変数名は、文字、数字、およびアンダースコア(_)のみで構成する必要があります。
  • 変数名を数字で始めることはできません。

これらのルールに従って、有効な変数名と無効な変数名の両方を見てみましょう。

有効 無効 なぜ無効なのか
userName user-name ハイフンは許可されていません
name4 4name 数字で始めることはできません
user $user 記号は使用できません
userName user name 複数の単語にすることはできません

さらに、変数に名前を付けるときは、大文字と小文字が区別されることに注意してください。 これらの名前userNameUSERNAMEUserName、およびuSERnAMEはすべて完全に異なる変数です。 プログラム内で同様の変数名を使用しないようにして、現在および将来の共同作業者と共同作業者の両方が変数をまっすぐに保つことができるようにすることをお勧めします。

変数では大文字と小文字が区別されますが、Goでは変数の最初の文字の大文字と小文字が特別な意味を持ちます。 変数が大文字で始まる場合、その変数は、宣言されたパッケージ(またはexported)の外部からアクセスできます。 変数が小文字で始まる場合、それは宣言されているパッケージ内でのみ使用できます。

var Email string
var password string

Emailは大文字で始まり、他のパッケージからアクセスできます。 passwordは小文字で始まり、宣言されているパッケージ内でのみアクセスできます。

Goでは、非常に簡潔な(または短い)変数名を使用するのが一般的です。 変数にuserNameuserのどちらを使用するかを選択すると、userを選択するのが慣用的になります。

スコープは、変数名の簡潔さにも影響します。 規則は、変数が存在するスコープが小さいほど、変数名は小さくなります。

names := []string{"Mary", "John", "Bob", "Anna"}
for i, n := range names {
	fmt.Printf("index: %d = %q\n", i, n)
}

変数namesをより広い範囲で使用するため、プログラムでの意味を覚えやすくするために、より意味のある名前を付けるのが一般的です。 ただし、i変数とn変数は、コードの次の行ですぐに使用し、その後は使用しません。このため、コードを読んでいる人がどこにいるのか混乱することはありません。使用される変数、またはそれらの意味。

次に、可変スタイルに関するいくつかの注意事項について説明します。 複数の単語の名前には、アンダースコアではなく、MixedCapsまたはmixedCapsを使用するスタイルです。

従来のスタイル 型破りなスタイル なぜ型破りなのか
userName user_name アンダースコアは従来のものではありません
i index indexよりもiの方が短いため、
serveHTTP serveHttp 頭字語は大文字にする必要があります

スタイルに関して最も重要なことは、一貫性を保つこと、そしてあなたが取り組むチームがスタイルに同意することです。

変数の再割り当て

「変数」という言葉が意味するように、Go変数は簡単に変更できます。 これは、再割り当てによって、以前に割り当てられた変数に別の値を接続できることを意味します。 プログラムの過程全体で、ユーザーが生成した値をすでに初期化された変数に受け入れる必要がある場合があるため、再割り当てできると便利です。 また、割り当てを以前に定義したものに変更する必要がある場合もあります。

変数を簡単に再割り当てできることを知っていると、他の誰かが書いた大規模なプログラムで作業するときに役立ちます。また、どの変数がすでに定義されているかが明確ではありません。

76の値を、タイプintiという変数に割り当ててから、42の新しい値を割り当てましょう。

package main

import "fmt"

func main() {
	i := 76
	fmt.Println(i)

	i = 42
	fmt.Println(i)
}
Output
76 42

この例は、最初に変数iに整数の値を割り当て、次に変数i42の値を割り当て直すことができることを示しています。

注: を宣言して変数を初期化する場合は、:=を使用できますが、すでに宣言されている変数の値を単純に変更する場合は、等号演算子(=)を使用する必要があります。

Goはtyped言語であるため、あるタイプを別のタイプに割り当てることはできません。 たとえば、値"Sammy"をタイプintの変数に割り当てることはできません。

i := 72
i = "Sammy"

異なるタイプを相互に割り当てようとすると、コンパイル時エラーが発生します。

Output
cannot use "Sammy" (type string) as type int in assignment

Goでは、変数名を複数回使用することはできません。

var s string
var s string
Output
s redeclared in this block

同じ変数名に対して短い変数宣言を複数回使用しようとすると、コンパイルエラーも発生します。 これは誤って発生する可能性があるため、エラーメッセージの意味を理解しておくと役立ちます。

i := 5
i := 10
Output
no new variables on left side of :=

変数宣言と同様に、変数の名前を考慮することで、将来プログラムを再検討するときに、プログラムの読みやすさが向上します。

複数の割り当て

Goを使用すると、同じ行内の複数の変数に複数の値を割り当てることもできます。 これらの各値は、異なるデータ型にすることができます。

j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Output
shark 2.05 15

この例では、変数jが文字列"shark"に割り当てられ、変数kがフロート2.05に割り当てられ、変数lは整数15に割り当てられました。

1行の複数の値に複数の変数を割り当てるこのアプローチにより、コードの行数を抑えることができます。 ただし、コードの行数を減らしても読みやすさを損なわないことが重要です。

グローバル変数とローカル変数

プログラム内で変数を使用する場合は、変数スコープを念頭に置くことが重要です。 変数のスコープは、特定のプログラムのコード内からアクセスできる特定の場所を指します。 つまり、特定のプログラムのすべての部分からすべての変数にアクセスできるわけではありません。一部の変数はグローバルになり、一部はローカルになります。

グローバル変数は関数の外部に存在します。 ローカル変数は関数内に存在します。

実際のグローバル変数とローカル変数を見てみましょう。

package main

import "fmt"


var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
}

func main() {
	printLocal()
	fmt.Println(g)
}
Output
local global

ここでは、var g = "global"を使用して、関数の外部にグローバル変数を作成します。 次に、関数printLocal()を定義します。 関数内では、lというローカル変数が割り当てられ、出力されます。 プログラムは、printLocal()を呼び出してから、グローバル変数gを出力することで終了します。

gはグローバル変数であるため、printLocal()で参照できます。 それを行うために前のプログラムを変更してみましょう:

package main

import "fmt"


var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
	fmt.Println(g)
}

func main() {
	printLocal()
	fmt.Println(g)
}
Output
local global global

まず、グローバル変数gvar g = "global"を宣言します。 main関数では、関数printLocalを呼び出します。この関数は、ローカル変数lを宣言し、fmt.Println(l)を出力します。 次に、printLocalは、グローバル変数gfmt.Println(g)を出力します。 gprintLocal内で定義されていませんが、グローバルスコープで宣言されているため、引き続きアクセスできます。 最後に、main関数はgも出力します。

次に、関数の外部でローカル変数を呼び出してみましょう。

package main

import "fmt"

var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
}

func main() {
	fmt.Println(l)
}

Output
undefined: l

割り当てられている関数の外部でローカル変数を使用することはできません。 これを行おうとすると、コンパイル時にundefinedエラーが発生します。

グローバル変数とローカル変数に同じ変数名を使用する別の例を見てみましょう。

package main

import "fmt"

var num1 = 5

func printNumbers() {
	num1 := 10
	num2 := 7  

	fmt.Println(num1)
	fmt.Println(num2)
}

func main() {
	printNumbers()
	fmt.Println(num1)
}
Output
10 7 5

このプログラムでは、num1変数を2回宣言しました。 最初に、グローバルスコープvar num1 = 5num1を宣言し、printNumbers関数のローカルスコープnum1 := 10内で宣言しました。 mainプログラムからnum1を印刷すると、5の値が印刷されていることがわかります。 これは、mainがグローバル変数宣言のみを参照するためです。 ただし、printNumbers関数からnum1を出力すると、ローカル宣言が表示され、10の値が出力されます。 printNumbersnum1という新しい変数を作成し、それに10の値を割り当てましたが、num1のグローバルインスタンスには影響しません。 5

変数を操作するときは、プログラムのどの部分が各変数にアクセスする必要があるかについても考慮する必要があります。 それに応じてグローバル変数またはローカル変数を採用します。 Goプログラム全体で、ローカル変数が一般的であることがわかります。

定数

定数は変数に似ていますが、宣言された後は変更できない点が異なります。 定数は、プログラムで複数回使用される値を定義するのに役立ちますが、変更することはできません。

たとえば、ショッピングカートシステムの税率を宣言する場合は、定数を使用して、プログラムのさまざまな領域で税を計算できます。 将来のある時点で、税率が変更された場合、プログラムの1つの場所でその値を変更するだけで済みます。 変数を使用した場合、プログラムのどこかで誤って値を変更し、計算が不適切になる可能性があります。

定数を宣言するには、次の構文を使用できます。

const shark = "Sammy"
fmt.Println(shark)
Output
Sammy

宣言された後に定数を変更しようとすると、コンパイル時エラーが発生します。

Output
cannot assign to shark

定数はuntypedにすることができます。 これは、整数型のデータなどの数値を操作するときに役立ちます。 定数がuntypedの場合、明示的に変換されますが、typed定数は変換されません。 定数を使用する方法を見てみましょう。

package main

import "fmt"

const (
	year     = 365
	leapYear = int32(366)
)

func main() {
	hours := 24
	minutes := int32(60)
	fmt.Println(hours * year)    
	fmt.Println(minutes * year)   
	fmt.Println(minutes * leapYear)
}
Output
8760 21900 21960

型を使用して定数を宣言すると、その正確な型になります。 ここで定数leapYearを宣言するときは、データ型int32として定義します。 したがって、これはtyped定数です。つまり、int32データ型でのみ動作できます。 year定数は型なしで宣言するため、untypedと見なされます。 このため、任意の整数データ型で使用できます。

hoursが定義されたとき、タイプhours := 24を明示的に指定しなかったため、タイプintであると推論されましたminutesを宣言したとき、それをint32minutes := int32(60)として明示的に宣言しました。

次に、各計算とそれが機能する理由を見ていきましょう。

hours * year

この場合、hoursintであり、yearsuntypedです。 プログラムがコンパイルされると、yearsintに明示的に変換され、乗算演算が成功します。

minutes * year

この場合、minutesint32であり、yearuntypedです。 プログラムがコンパイルされると、yearsint32に明示的に変換され、乗算演算が成功します。

minutes * leapYear

この場合、minutesint32であり、leapYearint32型付き定数です。 両方の変数がすでに同じタイプであるため、今回はコンパイラーが行うことは何もありません。

typedで互換性のない2つのタイプを乗算しようとすると、プログラムはコンパイルされません。

fmt.Println(hours * leapYear)
Output
invalid operation: hours * leapYear (mismatched types int and int32)

この場合、hoursintとして推測され、leapYearint32として明示的に宣言されました。 Goは型付き言語であるため、intint32は数学演算と互換性がありません。 それらを乗算するには、を使用して1つをint32またはintに変換する必要があります。

結論

このチュートリアルでは、Go内の変数の一般的なユースケースのいくつかを確認しました。 変数はプログラミングの重要な構成要素であり、プログラムで使用するデータ型の値を表すシンボルとして機能します。