變量是一個需要掌握的重要編程概念。它們是符號,代表你在程序中使用的值。
本教程將介紹一些變量基礎(chǔ)知識和在您創(chuàng)建的Go程序中使用它們的最佳實踐。
理解變量
用技術(shù)術(shù)語來說,變量是將一個存儲位置賦值給一個與符號名稱或標識符相關(guān)聯(lián)的值。在計算機程序中,我們使用變量名來引用存儲的值。
我們可以把變量想象成一個標簽,上面有一個名字,你把它和一個值聯(lián)系在一起。
假設(shè)我們有一個整數(shù)1032049348
,我們希望將它存儲在一個變量中,而不是不斷地重復(fù)輸入一個很長的數(shù)字。為了實現(xiàn)這一點,我們可以使用一個容易記住的名稱,比如變量i
。要在變量中存儲值,我們使用以下語法:
i := 1032049348
我們可以把這個變量想象成一個綁定在值上的標簽。
標簽上寫著變量名i
,并綁定到整數(shù)值1032049348
。
短語i:= 1032049348
是一個聲明和賦值語句,由以下幾個部分組成:
- 變量名(
i
) - 簡短的變量聲明賦值(
:=
) - 綁定到變量名(
1032049348
)的值 - Go推斷的數(shù)據(jù)類型(
int
)
我們將在下一節(jié)中看到如何顯式設(shè)置類型。
這些部分組成了一個語句,該語句將變量i
設(shè)置為整數(shù)1032049348
的值。
一旦我們設(shè)置一個變量等于一個值,我們就初始化或創(chuàng)建該變量。這樣做之后,就可以使用變量而不是值了。
一旦我們將i
設(shè)置為1032049348
,我們就可以使用i
來代替整數(shù),所以讓我們把它打印出來:
package main
import "fmt"
func main() {
i := 1032049348
fmt.Println(i)
}
Output1032049348
通過使用變量,我們還可以快速輕松地進行數(shù)學(xué)運算。使用i:= 1032049348
,我們可以用下面的語法減去整數(shù)813
:
fmt.Println(i - 813)
Output1032048535
在這個例子中,Go為我們做了數(shù)學(xué)計算,從變量i
中減去813,返回和1032048535
。
說到數(shù)學(xué),變量可以設(shè)置為與數(shù)學(xué)方程的結(jié)果相等。你也可以將兩個數(shù)字相加,并將和的值存儲在變量x
中:
x := 76 + 145
你可能已經(jīng)注意到,這個例子看起來很像代數(shù)。就像我們在公式和方程中使用字母和其他符號來表示數(shù)字和數(shù)量一樣,變量是表示數(shù)據(jù)類型值的符號名稱。為了正確的Go語法,您需要確保您的變量位于任何方程的左側(cè)。
讓我們繼續(xù)打印x
:
package main
import "fmt"
func main() {
x := 76 + 145
fmt.Println(x)
}
Output221
Go返回了值2212
,因為變量x
被設(shè)置為76
和145
的和。變量可以表示任何數(shù)據(jù)類型,而不僅僅是整數(shù):
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將返回該變量等效的內(nèi)容。讓我們使用字符串slice
數(shù)據(jù)類型的賦值語句:
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
函數(shù)通過調(diào)用slice
來打印出這個值。
變量的工作原理是在計算機中劃出一小塊內(nèi)存區(qū)域,用于接收指定的值,然后將這些值與該空間相關(guān)聯(lián)。
聲明變量
在Go中,有多種聲明變量的方法,在某些情況下,有多種方法聲明完全相同的變量和值。
我們可以聲明一個名為i
的數(shù)據(jù)類型為int
的變量,而無需初始化。這意味著我們將聲明一個空格來放置值,但不給它初始值:
var i int
這將創(chuàng)建一個聲明為i
的變量,數(shù)據(jù)類型為int
。
可以使用equal(=
)操作符初始化這個值,如下面的例子所示:
var i int = 1
在Go中,這兩種聲明形式都稱為長變量聲明。
我們也可以使用簡短的變量聲明:
i := 1
在這個例子中,我們有一個名為i
的變量,以及一個int
的數(shù)據(jù)類型。當我們不指定數(shù)據(jù)類型時,Go將推斷數(shù)據(jù)類型。
有了這三種聲明變量的方式,Go社區(qū)采用了以下習(xí)語:
- 只在不初始化變量時使用長形式
var i int
。 - 在聲明和初始化時使用縮寫形式
i:= 1
。 - 如果你不想去推斷你的數(shù)據(jù)類型,但你仍然想使用簡短的變量聲明,你可以使用以下語法將值包裝為所需的類型:
i := int64(1)
在Go中,初始化值時使用冗長的變量聲明形式不被認為是習(xí)慣用法:
var i int = 1
遵循Go社區(qū)通常是如何聲明變量的,這樣其他人就可以無縫地閱讀你的程序,這是一個很好的實踐。
零值
所有內(nèi)置類型都有一個0值。任何被賦值的變量都是可用的,即使它從未被賦值。我們可以看到以下類型的0值:
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
動詞。這告訴函數(shù)打印變量的data type
。
在Go中,因為所有的值都有0
值,所以我們不能像其他語言一樣有undefined
值。例如,在某些語言中,[boolean
]可以是undefined
、true
或false
,這允許變量有三種
狀態(tài)。在Go中,布爾值不能有超過“兩種”狀態(tài)。
命名變量:規(guī)則和風(fēng)格
變量的命名非常靈活,但有一些規(guī)則需要記住。
- 變量名只能是一個單詞(不能有空格)。
- 變量名只能由字母、數(shù)字和下劃線(
_
)組成。 - 變量名不能以數(shù)字開頭。
遵循這些規(guī)則,我們來看看有效和無效的變量名:
有效 | 無效 | 為什么無效 |
---|---|---|
userName |
user-name |
不允許連字符 |
name4 |
4name |
不能以數(shù)字開頭 |
user |
$user |
不能使用符號 |
userName |
user name |
不能超過一個單詞 |
此外,在命名變量時要記住區(qū)分大小寫。userName
、userName
、userName
和userName
都是完全不同的變量。最好的做法是避免在程序中使用相似的變量名,以確保你和你的合作者(現(xiàn)在和將來)都能正確使用變量。
雖然變量是區(qū)分大小寫的,但變量的第一個字母的大小寫在Go中具有特殊意義。如果變量以大寫字母開頭,那么該變量可以在聲明它的包(或export
)之外訪問。如果變量以小寫字母開頭,那么它只能在聲明它的包中使用。
var Email string
var password string
Email
以大寫字母開頭,可以被其他包訪問。password
以小寫字母開頭,并且只能在聲明它的包中訪問。
在Go中使用非常簡潔(或簡短)的變量名是很常見的。如果要在變量userName
和user
之間選擇,按慣例應(yīng)該選擇user
。
作用域也有助于簡化變量名。規(guī)則是,變量的作用域越小,變量名就越小:
names := []string{"Mary", "John", "Bob", "Anna"}
for i, n := range names {
fmt.Printf("index: %d = %q\n", i, n)
}
我們在更大的作用域中使用變量names
,因此通常會給它一個更有意義的名字,以幫助記住它在程序中的含義。然而,我們在下一行代碼中立即使用i
和n
變量,然后不會再次使用它們……正因為如此,閱讀代碼的人不會混淆變量在哪里使用,或者它們的含義。
接下來,讓我們介紹一些關(guān)于變量風(fēng)格的注意事項?,F(xiàn)在的樣式是使用MixedCaps
或MixedCaps
來代替多單詞名稱中的下劃線。
常規(guī)風(fēng)格 | 非常規(guī)風(fēng)格 | 為什么是非常規(guī) |
---|---|---|
userName |
user_name |
下劃線不是常規(guī)的 |
i |
index |
i 比index 更短 |
serveHTTP |
serveHttp |
首字母縮寫應(yīng)該大寫 |
關(guān)于風(fēng)格,最重要的是保持一致,并且你所工作的團隊都認同這種風(fēng)格。
重新分配變量
正如“變量”一詞所暗示的,我們可以隨時更改Go變量。這意味著我們可以通過重新賦值將不同的值與之前賦值的變量聯(lián)系起來。能夠重新賦值是有用的,因為在整個程序過程中,我們可能需要接受用戶生成的值到已經(jīng)初始化的變量中。我們可能還需要修改之前定義的賦值。
在別人編寫的大型程序中,如果不清楚哪些變量已經(jīng)定義,那么很容易對變量重新賦值是很有用的。
讓我們把76
的值賦給一個類型為int
的變量i
,然后給它賦一個新值42
:
package main
import "fmt"
func main() {
i := 76
fmt.Println(i)
i = 42
fmt.Println(i)
}
Output76
42
這個例子表明,我們可以先給變量i
賦值一個整數(shù),然后再給變量i
重新賦值,這次賦值為42
。
注意:當你聲明并初始化一個變量時,你可以使用:=
,但是,當你想簡單地改變一個已經(jīng)聲明的變量的值時,你只需要使用相等操作符(=
)。
因為Go是一種typed
語言,我們不能將一種類型指定給另一種類型。例如,我們不能將值"Sammy"
賦值給int
類型的變量:
i := 72
i = "Sammy"
試圖為彼此分配不同的類型將導(dǎo)致編譯時錯誤:
Outputcannot use "Sammy" (type string) as type int in assignment
Go不允許我們多次使用一個變量名:
var s string
var s string
Outputs redeclared in this block
如果我們多次嘗試對同一個變量名使用簡短的變量聲明,我們還會收到編譯錯誤。這種情況可能是偶然發(fā)生的,所以理解錯誤消息的含義是很有幫助的:
i := 5
i := 10
Outputno new variables on left side of :=
與變量聲明類似,考慮變量的命名可以提高程序的可讀性,對你和其他人來說都是如此。
多個賦值
Go還允許我們在同一行中為多個變量分配多個值。這些值都可以是不同的數(shù)據(jù)類型:
j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Outputshark
2.05
15
在這個例子中,變量j
被賦值給字符串"shark"
,變量k
被賦值給浮點數(shù)2.05
,變量l
被賦值給整數(shù)15
。
這種在一行中將多個變量賦值給多個值的方法可以減少代碼的行數(shù)。然而,重要的是不要為了更少的代碼行而犧牲可讀性。
全局變量和局部變量
當在程序中使用變量時,記住變量作用域是很重要的。變量的作用域指的是在給定程序的代碼中可以訪問變量的特定位置。也就是說,并不是所有變量都可以在程序的所有部分中訪問,有些變量是全局變量,有些是局部變量。
全局變量存在于函數(shù)之外。局部變量存在于函數(shù)中。
讓我們看一下全局變量和局部變量的實際作用:
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"
在函數(shù)外部創(chuàng)建一個全局變量。然后我們定義函數(shù)printLocal()
。在函數(shù)內(nèi)部,一個名為l
的局部變量被賦值,然后被打印出來。程序以調(diào)用printLocal()
結(jié)束,然后打印全局變量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
函數(shù)中,我們調(diào)用函數(shù)printLocal
,它聲明了一個局部變量l
并打印出來,fmt.Println(l)
。然后,printLocal
打印出全局變量g
, fmt.Println(g)
。即使g
沒有在printLocal
中定義,它仍然可以被訪問,因為它是在全局作用域中聲明的。最后,main
函數(shù)也打印出g
。
現(xiàn)在嘗試在函數(shù)外部調(diào)用局部變量:
package main
import "fmt"
var g = "global"
func printLocal() {
l := "local"
fmt.Println(l)
}
func main() {
fmt.Println(l)
}
Outputundefined: l
我們不能在賦值局部變量的函數(shù)之外使用它。如果你嘗試這樣做,你會在編譯時收到一個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
變量。首先,我們在全局作用域中聲明num1
, var num1 = 5
,然后在printNumbers
函數(shù)的局部作用域中聲明num1:= 10
。當我們在main
程序中打印num1
時,我們看到5
的值被打印出來了。這是因為main
只能看到全局變量的聲明。然而,當我們從printNumbers
函數(shù)打印出num1
時,它看到了本地聲明,并將打印出10
的值。即使printNumbers
創(chuàng)建了一個名為num1
的新變量,并將值10
賦給它,它也不會影響num1
的全局實例的值5
。
使用變量時,你還需要考慮程序的哪些部分需要訪問這些變量;相應(yīng)地采用全局或局部變量。在Go程序中,您會發(fā)現(xiàn)局部變量通常更常見。
常量
常量類似于變量,只是一旦聲明就不能修改。常量用于定義在程序中會多次使用但不能更改的值。
例如,如果我們想聲明購物車系統(tǒng)的稅率,可以使用一個常量,然后在程序的不同區(qū)域計算稅率。在未來的某個時候,如果稅率改變了,我們只需要改變程序中的一個地方。如果我們使用了一個變量,就有可能在程序的某個地方不小心改變它的值,從而導(dǎo)致錯誤的計算。
要聲明常量,可以使用以下語法:
const shark = "Sammy"
fmt.Println(shark)
OutputSammy
如果我們試圖在聲明常量后修改它,會得到編譯時錯誤:
Outputcannot assign to shark
常量可以是untyped
的。這在處理整數(shù)類型的數(shù)據(jù)時很有用。如果常量是untyped
,它會被顯式轉(zhuǎn)換,而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
時,我們將它定義為數(shù)據(jù)類型int32
。因此它是一個typed
常量,這意味著它只能操作int32
數(shù)據(jù)類型。我們聲明的year
常量沒有類型,所以它被認為是無類型
。因此,你可以將它用于任何整數(shù)數(shù)據(jù)類型。
當定義hours
時,它推斷它的類型是int
,因為我們沒有顯式地給它一個類型hours:= 24
。當我們聲明minutes
時,我們顯式地聲明它為int32
, minutes:= int32(60)
。
現(xiàn)在,讓我們來看看每個計算以及它為什么可以工作:
hours * year
在這個例子中,hours
是一個int
類型,而years
是未類型。當程序編譯時,它顯式地將years
轉(zhuǎn)換為int
,這允許乘法操作成功。
minutes * year
在這個例子中,minutes
是int32
,而year
是未類型。當程序編譯時,它顯式地將years
轉(zhuǎn)換為int32
,這允許乘法操作成功。
minutes * leapYear
在這個例子中,minutes
是一個int32
,而leapYear
是一個int32
類型的常量。這一次編譯器什么都不用做,因為兩個變量的類型已經(jīng)相同了。
如果我們嘗試將兩個typed
且不兼容的類型相乘,程序?qū)o法編譯:
fmt.Println(hours * leapYear)
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
在這個例子中,hours
被推斷為int
類型,而leapYear
被明確聲明為int32
類型。因為Go是一種類型語言,int
和int32
不兼容數(shù)學(xué)運算。要將它們相乘,你需要將1轉(zhuǎn)換為int32
或int
文章來源:http://www.zghlxwxcb.cn/news/detail-727481.html
總結(jié)
在本教程中,我們回顧了Go中變量的一些常見用例。變量是編程的重要組成部分,它作為符號,代表程序中使用的數(shù)據(jù)類型的值。文章來源地址http://www.zghlxwxcb.cn/news/detail-727481.html
到了這里,關(guān)于如何在Go中使用變量和常量的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!