您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么快速學會Go的struct數據類型”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么快速學會Go的struct數據類型”吧!
結構是表示字段集合的用戶定義類型。它可以用于將數據分組為單個單元而不是將每個數據作為單獨的值的地方。
例如,員工有firstName、lastName和age。將這三個屬性分組到一個名為Employee
。
type Employee struct { firstName string lastName string age int }
上面的代碼段聲明了一個結構類型Employee,其中包含字段firstName、lastName和age。上面的Employee結構稱為命名結構,因為它創建了一個名為Employme的新數據類型,可以使用該數據類型創建Employ結構。
通過在一行中聲明屬于同一類型的字段,然后在類型名稱后面加上該字段,也可以使該結構更加緊湊。在上面的struct中,firstName和lastName屬于同一類型字符串,因此該struct可以重寫為:
type Employee struct { firstName, lastName string age int }
盡管上面的語法節省了幾行代碼,但它并沒有使字段聲明顯式。請避免使用上述語法。
讓我們使用以下簡單程序聲明一個命名的structEmployee。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { //creating struct specifying field names emp1 := Employee{ firstName: "Sam", age: 25, salary: 500, lastName: "Anderson", } //creating struct without specifying field names emp2 := Employee{"Thomas", "Paul", 29, 800} fmt.Println("Employee 1", emp1) fmt.Println("Employee 2", emp2) }
在上述程序的第7行中,我們創建了一個命名的結構類型Employee。在上述程序的第17行中,emp1結構是通過為每個字段名指定值來定義的。聲明結構類型時,字段的順序不必與字段名的順序相同。在這種情況下。我們已更改lastName的位置并將其移到末尾。這將不會有任何問題。
在上述程序的第25行中,通過省略字段名來定義emp2。在這種情況下,必須保持字段的順序與結構聲明中指定的順序相同。請避免使用此語法,因為它會使您難以確定哪個字段的值。我們在此處指定此格式只是為了理解這也是一個有效語法:)
以上程序打印為:
Employee 1 {Sam Anderson 25 500}
Employee 2 {Thomas Paul 29 800}
可以在不創建新數據類型的情況下聲明結構。這些類型的結構稱為匿名結構。
package main import ( "fmt" ) func main() { emp3 := struct { firstName string lastName string age int salary int }{ firstName: "Andreah", lastName: "Nikola", age: 31, salary: 5000, } fmt.Println("Employee 3", emp3) }
在上述程序的第8行中,定義了一個匿名結構變量emp3。正如我們已經提到的,這個結構稱為anonymous,因為它只創建一個新的結構變量emp3,而沒有定義任何新的結構類型,如命名結構。
上述代碼打印的結果為:
Employee 3 {Andreah Nikola 31 5000}
運算符.
用于訪問結構的各個字段。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { emp6 := Employee{ firstName: "Sam", lastName: "Anderson", age: 55, salary: 6000, } fmt.Println("First Name:", emp6.firstName) fmt.Println("Last Name:", emp6.lastName) fmt.Println("Age:", emp6.age) fmt.Printf("Salary: $%d\n", emp6.salary) emp6.salary = 6500 fmt.Printf("New Salary: $%d", emp6.salary) }
上面程序中的emp6.firstName訪問emp6結構的firstName字段。在第25行中,我們修改了員工的工資。此程序打印。
First Name: Sam
Last Name: Anderson
Age: 55
Salary: $6000
New Salary: $6500
當定義了一個結構并且沒有用任何值顯式初始化它時,默認情況下會為該結構的字段分配零值。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { var emp4 Employee //zero valued struct fmt.Println("First Name:", emp4.firstName) fmt.Println("Last Name:", emp4.lastName) fmt.Println("Age:", emp4.age) fmt.Println("Salary:", emp4.salary) }
上面的程序定義了emp4,但沒有用任何值初始化。因此,firstName和lastName被指定為字符串的零值,字符串為空字符串“”,age和salary被指定為零值int,即0。此程序打印
First Name:
Last Name:
Age: 0
Salary: 0
也可以為某些字段指定值,而忽略其余字段。在這種情況下,被忽略的字段被賦值為零。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { emp5 := Employee{ firstName: "John", lastName: "Paul", } fmt.Println("First Name:", emp5.firstName) fmt.Println("Last Name:", emp5.lastName) fmt.Println("Age:", emp5.age) fmt.Println("Salary:", emp5.salary) }
在上面的程序中。第16號和第17號,firstName和lastName被初始化,而年齡和薪水沒有初始化。因此,年齡和工資被指定為零值。此程序輸出:
First Name: John
Last Name: Paul
Age: 0
Salary: 0
也可以創建指向結構的指針。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { emp8 := &Employee{ firstName: "Sam", lastName: "Anderson", age: 55, salary: 6000, } fmt.Println("First Name:", (*emp8).firstName) fmt.Println("Age:", (*emp8).age) }
上面程序中的emp8是指向Employee結構的指針。(*emp8)。firstName是訪問emp8結構的firstName字段的語法。此程序打印:
First Name: Sam
Age: 55
Go語言為我們提供了使用emp8.firstName而不是顯式取消引用(*emp8)的選項。firstName以訪問firstName字段。
package main import ( "fmt" ) type Employee struct { firstName string lastName string age int salary int } func main() { emp8 := &Employee{ firstName: "Sam", lastName: "Anderson", age: 55, salary: 6000, } fmt.Println("First Name:", emp8.firstName) fmt.Println("Age:", emp8.age) }
我們已經使用emp8.firstName訪問上述程序中的firstName字段,該程序還輸出:
First Name: Sam
Age: 55
可以使用只包含類型而不包含字段名的字段創建結構。這類字段稱為匿名字段。下面的代碼段創建了一個struct Person,它有兩個匿名字段string和int:
type Person struct { string int }
即使匿名字段沒有顯式名稱,默認情況下,匿名字段的名稱是其類型的名稱。例如,在上面的Person結構中,雖然字段是匿名的,但默認情況下它們采用字段類型的名稱。所以Person結構有兩個字段,分別是名稱字符串和int。
package main import ( "fmt" ) type Person struct { string int } func main() { p1 := Person{ string: "naveen", int: 50, } fmt.Println(p1.string) fmt.Println(p1.int) }
在上述程序的第17行和第18行中,我們訪問Person結構的匿名字段,使用它們的類型作為字段名,分別是string和int。上述程序的輸出為:
naveen
50
結構可能包含字段,而字段又是結構。這些類型的結構稱為嵌套結構。
package main import ( "fmt" ) type Address struct { city string state string } type Person struct { name string age int address Address } func main() { p := Person{ name: "Naveen", age: 50, address: Address{ city: "Chicago", state: "Illinois", }, } fmt.Println("Name:", p.name) fmt.Println("Age:", p.age) fmt.Println("City:", p.address.city) fmt.Println("State:", p.address.state) }
上述程序中的Person結構具有字段地址,而字段地址又是一個結構。此程序打印:
Name: Naveen
Age: 50
City: Chicago
State: Illinois
屬于結構中匿名結構字段的字段稱為提升字段,因為可以像訪問包含匿名結構字段結構一樣訪問它們。我可以理解這個定義相當復雜,所以讓我們深入研究一些代碼來理解它。
type Address struct { city string state string } type Person struct { name string age int Address }
在上面的代碼段中,Person結構有一個匿名字段Address,它是一個結構。現在,Address的字段,即city和state,被稱為promoted字段,因為可以像直接在Person結構本身中聲明一樣訪問它們。
package main import ( "fmt" ) type Address struct { city string state string } type Person struct { name string age int Address } func main() { p := Person{ name: "Naveen", age: 50, Address: Address{ city: "Chicago", state: "Illinois", }, } fmt.Println("Name:", p.name) fmt.Println("Age:", p.age) fmt.Println("City:", p.city) //city is promoted field fmt.Println("State:", p.state) //state is promoted field }
在上面程序的第29行和第30行中,可以訪問提升字段city和state,就好像它們是使用語法p.city和p.state在結構p中聲明的一樣。此程序打印:
Name: Naveen
Age: 50
City: Chicago
State: Illinois
如果結構類型以大寫字母開頭,則它是導出類型,可以從其他包訪問。類似地,如果結構的字段以caps開頭,則可以從其他包訪問它們。讓我們編寫一個具有自定義包的程序來更好地理解這一點。在Documents目錄中創建名為structs的文件夾。請隨意在任何您喜歡的地方創建它。我更喜歡我的文檔目錄。
mkdir ~/Documents/structs
創建一個gomod,并命名為structs
。
cd ~/Documents/structs/
go mod init structs
創建另外一個目錄computer
申明一個結構體。
mkdir computer
創建一個spec.go
文件,并寫入如下內容:
package computer type Spec struct { //exported struct Maker string //exported field Price int //exported field model string //unexported field }
上面的代碼片段創建了一個程序包計算機,其中包含一個導出的結構類型Spec,其中有兩個導出的字段Maker和Price,以及一個未導出的字段模型。讓我們從主包導入這個包并使用Spec結構。
創建名為main的文件。進入structs目錄并在main.go中編寫以下程序:
package main import ( "structs/computer" "fmt" ) func main() { spec := computer.Spec { Maker: "apple", Price: 50000, } fmt.Println("Maker:", spec.Maker) fmt.Println("Price:", spec.Price) }
這個結構體如下結構體:
├── structs
│ ├── computer
│ │ └── spec.go
│ ├── go.mod
│ └── main.go
在上面程序的第4行,我們導入計算機包。在第13行和第14行,我們訪問struct Spec的兩個導出字段Maker和Price。這個程序可以通過執行命令go-install,然后執行structs命令來運行。
go install
structs
運行之后如下結果:
Maker: apple
Price: 50000
如果我們試圖訪問未報告的字段模型,編譯器會抱怨。更換main的內容。使用以下代碼。
package main import ( "structs/computer" "fmt" ) func main() { spec := computer.Spec { Maker: "apple", Price: 50000, model: "Mac Mini", } fmt.Println("Maker:", spec.Maker) fmt.Println("Price:", spec.Price) }
在上述程序的第12行中,我們嘗試訪問未報告的字段模型。運行此程序將導致編譯錯誤。
# structs
./main.go:12:13: unknown field 'model' in struct literal of type computer.Spec
由于模型字段未報告,因此無法從其他包訪問它。
結構是值類型,如果它們的每個字段都是可比較的,則可以進行比較。如果兩個結構變量的對應字段相等,則認為它們相等。
package main import ( "fmt" ) type name struct { firstName string lastName string } func main() { name1 := name{ firstName: "Steve", lastName: "Jobs", } name2 := name{ firstName: "Steve", lastName: "Jobs", } if name1 == name2 { fmt.Println("name1 and name2 are equal") } else { fmt.Println("name1 and name2 are not equal") } name3 := name{ firstName: "Steve", lastName: "Jobs", } name4 := name{ firstName: "Steve", } if name3 == name4 { fmt.Println("name3 and name4 are equal") } else { fmt.Println("name3 and name4 are not equal") } }
在上面的程序中,名稱結構類型包含兩個字符串字段。由于字符串是可比較的,因此可以比較類型名的兩個結構變量。在上面的程序中,name1和name2相等,而name3和name4不相等。此程序將輸出:
name1 and name2 are equal
name3 and name4 are not equal
如果結構變量包含不可比較的字段,那么它們就不可比較(感謝reddit的alasija指出這一點)。
package main import ( "fmt" ) type image struct { data map[int]int } func main() { image1 := image{ data: map[int]int{ 0: 155, }} image2 := image{ data: map[int]int{ 0: 155, }} if image1 == image2 { fmt.Println("image1 and image2 are equal") } }
在上面的程序中,圖像結構類型包含類型映射的字段數據。地圖是不可比較的,因此無法比較image1和image2。如果運行此程序,編譯將失敗并返回錯誤。
./prog.go:20:12: invalid operation: image1 == image2 (struct containing map[int]int cannot be compared)
到此,相信大家對“怎么快速學會Go的struct數據類型”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。