Variablesは、習得するための重要なプログラミング概念です。 これらは、プログラムで使用している値を表すシンボルです。
このチュートリアルでは、作成するGoプログラム内で使用するためのいくつかの変数の基本とベストプラクティスについて説明します。
変数を理解する
技術的には、変数は、シンボル名または識別子に関連付けられた値に保存場所を割り当てます。 変数名を使用して、コンピュータープログラム内で保存された値を参照します。
変数は、値が関連付けられた名前を持つラベルと考えることができます。
整数1032049348
があり、長い数値を何度も繰り返し入力するのではなく、変数に格納したいとします。 これを実現するために、変数i
のように、覚えやすい名前を使用できます。 変数に値を保存するには、次の構文を使用します。
i := 1032049348
この変数は、値に関連付けられたラベルのように考えることができます。
ラベルには変数名i
が書き込まれ、整数値1032049348
に関連付けられています。
フレーズi := 1032049348
は、いくつかの部分で構成される宣言および代入ステートメントです。
-
変数名(
i
) -
短い変数宣言の割り当て(
:=
) -
変数名に関連付けられている値(
1032049348
) -
Go(
int
)
によって推測されるデータ型
次のセクションでタイプを明示的に設定する方法については後で説明します。
これらの部分が一緒になって、変数i
を整数1032049348
の値に等しく設定するステートメントを構成します。
変数を値に設定するとすぐに、initializeまたはその変数を作成します。 これが完了すると、値の代わりに変数を使用する準備が整います。
i
を1032049348
の値と等しく設定したら、整数の代わりにi
を使用できるので、次のように出力します。
package main
import "fmt"
func main() {
i := 1032049348
fmt.Println(i)
}
Output1032049348
変数を使用して、すばやく簡単に数学を実行することもできます。 i := 1032049348
を使用すると、次の構文で整数値813
を減算できます。
fmt.Println(i - 813)
Output1032048535
この例では、Goが計算を行い、変数i
から813を減算して、合計1032048535
を返します。
数学といえば、変数は数学方程式の結果に等しく設定できます。 2つの数値を加算して、合計の値を変数x
に格納することもできます。
x := 76 + 145
この例は代数に似ていることに気づいたかもしれません。 式や方程式内で数字や数量を表すために文字や他の記号を使用するのと同じように、変数はデータ型の値を表す記号名です。 正しいGo構文を得るには、変数が方程式の左側にあることを確認する必要があります。
先に進んで、x
を出力しましょう:
package main
import "fmt"
func main() {
x := 76 + 145
fmt.Println(x)
}
Output221
変数x
が76
と145
の合計に等しく設定されているため、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では、変数を宣言する方法がいくつかあり、場合によっては、まったく同じ変数と値を宣言する方法が複数あります。
初期化せずに、データ型int
のi
という変数を宣言できます。 これは、値を入れるスペースを宣言しますが、初期値を与えないことを意味します。
var i int
これにより、データ型int
のi
として宣言された変数が作成されます。
次の例のように、equal(=
)演算子を使用して値を初期化できます。
var i int = 1
Goでは、これらの形式の宣言は両方ともlong variable declarationsと呼ばれます。
short variable declarationを使用することもできます。
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)
}
Outputvar a int = 0
var b string = ""
var c float64 = 0
var d bool = false
fmt.Printf
ステートメントで%T
動詞を使用しました。 これは、変数のdata type
を出力するように関数に指示します。
Goでは、すべての値にzero
値があるため、他の言語のようにundefined
値を持つことはできません。 たとえば、一部の言語のboolean
は、undefined
、true
、またはfalse
であり、変数にthree
状態を許可します。 Goでは、ブール値に対してtwo
を超える状態を持つことはできません。
変数の命名:ルールとスタイル
変数の命名は非常に柔軟ですが、留意すべきいくつかのルールがあります。
-
変数名は1つの単語のみである必要があります(スペースなしなど)。
-
変数名は、文字、数字、およびアンダースコア(
_
)のみで構成する必要があります。 -
変数名は数字で始めることはできません。
これらのルールに従って、有効な変数名と無効な変数名の両方を見てみましょう。
有効 | 無効 | なぜ無効なのか |
---|---|---|
|
|
ハイフンは許可されていません |
|
|
数字で始めることはできません |
|
|
記号は使用できません |
|
|
複数の単語にすることはできません |
さらに、変数に名前を付けるときは、大文字と小文字が区別されることに注意してください。 これらの名前userName
、USERNAME
、UserName
、およびuSERnAME
は、すべて完全に異なる変数です。 プログラム内で同様の変数名を使用しないようにして、現在および将来の共同作業者が変数をまっすぐに保つことができるようにすることをお勧めします。
変数では大文字と小文字が区別されますが、Goでは変数の最初の文字の大文字と小文字に特別な意味があります。 変数が大文字で始まる場合、その変数は、宣言されたパッケージ(またはexported
)の外部からアクセスできます。 変数が小文字で始まる場合、変数は宣言されているパッケージ内でのみ使用可能です。
var Email string
var password string
Email
は大文字で始まり、他のパッケージからアクセスできます。 password
は小文字で始まり、宣言されているパッケージ内でのみアクセスできます。
Goでは、非常に簡潔な(または短い)変数名を使用するのが一般的です。 変数にuserName
とuser
のどちらを使用するかを選択すると、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
を使用するスタイルです。
従来のスタイル | 型破りなスタイル | なぜ型破りなのか |
---|---|---|
|
|
アンダースコアは従来のものではありません |
|
|
|
|
|
頭字語は大文字にする必要があります |
スタイルについて最も重要なことは、一貫性を保つことであり、あなたが取り組むチームはスタイルに同意することです。
変数の再割り当て
「変数」という言葉が示すように、Go変数は簡単に変更できます。 これは、再割り当てによって以前に割り当てられた変数に別の値を接続できることを意味します。 プログラムの過程を通じて、ユーザーが生成した値を既に初期化された変数に受け入れる必要がある場合があるため、再割り当てできると便利です。 また、割り当てを以前に定義したものに変更する必要があります。
変数を簡単に再割り当てできることを知っていると、他の誰かが書いた大きなプログラムで作業するときに役立ちます。また、どの変数が既に定義されているかは明確ではありません。
76
の値をint
タイプのi
という変数に割り当ててから、新しい値42
を割り当てましょう。
package main
import "fmt"
func main() {
i := 76
fmt.Println(i)
i = 42
fmt.Println(i)
}
Output76
42
この例は、最初に変数i
に整数の値を割り当て、次に変数i
に再割り当てして今回は42
の値を割り当てることができることを示しています。
[.note]#Note:andで変数の初期化を宣言する場合は、:=
を使用できますが、すでに宣言されている変数の値を単純に変更する場合は、必要なのは等しい演算子を使用するには(=
)。
#
Goはtyped
言語であるため、あるタイプを別のタイプに割り当てることはできません。 たとえば、値"Sammy"
をタイプint
の変数に割り当てることはできません。
i := 72
i = "Sammy"
異なる型を互いに割り当てようとすると、コンパイル時エラーが発生します。
Outputcannot use "Sammy" (type string) as type int in assignment
Goでは、変数名を複数回使用することはできません。
var s string
var s string
Outputs redeclared in this block
同じ変数名に対して短い変数宣言を複数回使用しようとすると、コンパイルエラーも発生します。 これは誤って発生する可能性があるため、エラーメッセージの意味を理解しておくと役立ちます。
i := 5
i := 10
Outputno new variables on left side of :=
変数宣言と同様に、変数の命名を考慮することで、将来再訪する際に、あなたや他の人にとってプログラムの可読性が向上します。
複数の割り当て
Goでは、同じ行内の複数の変数に複数の値を割り当てることもできます。 これらの各値は、異なるデータ型にすることができます。
j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Outputshark
2.05
15
この例では、変数j
が文字列"shark"
に割り当てられ、変数k
がフロート2.05
に割り当てられ、変数l
が割り当てられました。整数15
に。
1行で複数の変数に複数の変数を割り当てるこのアプローチにより、コードの行数を抑えることができます。 ただし、より少ないコード行で読みやすさを損なわないことが重要です。
グローバル変数とローカル変数
プログラム内で変数を使用するときは、variable scopeを覚えておくことが重要です。 変数のスコープとは、特定のプログラムのコード内からアクセスできる特定の場所を指します。 つまり、特定のプログラムのすべての部分からすべての変数にアクセスできるわけではありません。一部の変数はグローバルになり、一部はローカルになります。
グローバル変数は関数の外部に存在します。 ローカル変数は関数内に存在します。
実際のグローバル変数とローカル変数を見てみましょう。
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
}
func main() {
printLocal()
fmt.Println(g)
}
Outputlocal
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)
}
Outputlocal
global
global
まず、グローバル変数g
、var g = "global"
を宣言します。 main
関数では、関数printLocal
を呼び出します。この関数は、ローカル変数l
を宣言し、それを出力しますfmt.Println(l)
。 次に、printLocal
はグローバル変数g
、fmt.Println(g)
を出力します。 g
はprintLocal
内で定義されていませんが、グローバルスコープで宣言されているため、引き続きアクセスできます。 最後に、main
関数はg
も出力します。
次に、関数の外部でローカル変数を呼び出してみましょう。
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
}
func main() {
fmt.Println(l)
}
Outputundefined: 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)
}
Output10
7
5
このプログラムでは、num1
変数を2回宣言しました。 最初に、グローバルスコープvar num1 = 5
でnum1
を宣言し、printNumbers
関数num1 := 10
のローカルスコープ内で宣言しました。 main
プログラムからnum1
を出力すると、5
の値が出力されます。 これは、main
がグローバル変数宣言のみを参照するためです。 ただし、printNumbers
関数からnum1
を出力すると、ローカル宣言が表示され、10
の値が出力されます。 printNumbers
はnum1
という新しい変数を作成し、それに値10
を割り当てましたが、値が5
のnum1
のグローバルインスタンスには影響しません。 s。
変数を操作するときは、プログラムのどの部分が各変数にアクセスする必要があるかを考慮する必要もあります。それに応じてグローバル変数またはローカル変数を採用します。 Goプログラムでは、一般的にローカル変数がより一般的であることがわかります。
定数
定数は変数に似ていますが、宣言されると変更できない点が異なります。 定数は、プログラムで複数回使用される値を定義するのに役立ちますが、変更することはできません。
たとえば、ショッピングカートシステムの税率を宣言する場合、定数を使用して、プログラムのさまざまな領域で税を計算できます。 将来のある時点で、税率が変更された場合、プログラムの1つの場所でその値を変更するだけで済みます。 変数を使用した場合、プログラムのどこかで誤って値を変更する可能性があり、不適切な計算になる可能性があります。
定数を宣言するには、次の構文を使用できます。
const shark = "Sammy"
fmt.Println(shark)
OutputSammy
宣言後に定数を変更しようとすると、コンパイル時エラーが発生します。
Outputcannot 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)
}
Output8760
21900
21960
型で定数を宣言すると、その正確な型になります。 ここで定数leapYear
を宣言するときは、データ型int32
として定義します。 したがって、これはtyped
定数です。つまり、int32
データ型でのみ動作できます。 型なしで宣言するyear
定数なので、untyped
と見なされます。 このため、任意の整数データ型で使用できます。
hours
が定義されたとき、タイプhours := 24
を明示的に指定しなかったため、タイプint
であることがinferredになりました。 minutes
を宣言したとき、それをint32
、minutes := int32(60)
として明示的に宣言しました。
それでは、各計算とそれが機能する理由を見ていきましょう。
hours * year
この場合、hours
はint
であり、years
はuntypedです。 プログラムがコンパイルされると、years
がint
に明示的に変換され、乗算演算が成功します。
minutes * year
この場合、minutes
はint32
であり、year
はuntypedです。 プログラムがコンパイルされると、years
がint32
に明示的に変換され、乗算演算が成功します。
minutes * leapYear
この場合、minutes
はint32
であり、leapYear
はint32
のtyped定数です。 両方の変数がすでに同じ型であるため、今回コンパイラーが行うことはありません。
typed
で互換性のない2つの型を乗算しようとすると、プログラムはコンパイルされません。
fmt.Println(hours * leapYear)
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
この場合、hours
はint
として推測され、leapYear
はint32
として明示的に宣言されました。 Goは型付き言語であるため、int
とint32
は数学演算と互換性がありません。 それらを乗算するには、to convert one to a int32
or an int
が必要になります。
結論
このチュートリアルでは、Go内の変数の一般的なユースケースのいくつかを確認しました。 変数はプログラミングの重要な構成要素であり、プログラムで使用するデータ型の値を表すシンボルとして機能します。