go int 转切片_一文掌握GO语言实战技能(二)
- Go 數(shù)組
- Go 切片
- Go 變量和內存地址
- Go Map 類型
- Go 面向對象編程
- Go 方法的定義
GO 數(shù)組
數(shù)組是同一類型的元素集合。Go中的數(shù)組下標從0開始,因此長度為n的數(shù)組下標范圍是[0, n-1]。
整數(shù)數(shù)組中元素默認初始化為0,字符串數(shù)組中的元素默認初始化為""。
?var?a?[3]int?a[0]?=?10
?a[1]?=?20
?
var?a?[3]int?=?[3]int{10,?20,?30}
//定義時數(shù)組初始化
//數(shù)組初始化
?var?a?[3]int?=?[3]int{10,?20,?30}
//定義時數(shù)組初始化
a?:=?[3]int{10,?20,?30}
//定義時數(shù)組初始化
a?:=?[...]int{10,?20,?30}
//定義時數(shù)組初始化
?
a?:=?[3]int{10}
//定義時數(shù)組初始化
a?:=?[3]int{2:10}
//定義時數(shù)組初始化
- 數(shù)組?度是類型的?部分
a[0]?=?10
a[1]?=?20
a[2]?=?30
var?b?[5]int
b=a
//a、b是不同類型的數(shù)組,不能賦值
- len 內置函數(shù)
a[0]?=?10
a[1]?=?20
a[2]?=?30
fmt.Printf(“l(fā)en:%d\n”,?len(a))
- 數(shù)組的遍歷
a. 下標進行遍歷
b. range 函數(shù)進行遍歷
range函數(shù)是個神奇而有趣的內置函數(shù),你可以使用它來遍歷數(shù)組,切片和字典。
當用于遍歷數(shù)組和切片的時候,range函數(shù)返回索引和元素。
當用于遍歷字典的時候,range函數(shù)返回字典的鍵和值。
import?"fmt"
func?main()?{
????var?a?[3]int
????a[0]?=?10
????a[1]?=?20
????a[2]?=?30
????//?使用下標遍歷
????for?i?:=?0;?i???????//?fmt.Printf(a[i]?+?"?")
????}
?
????for?index,?val?:=?range?a?{
??????//?fmt.Printf(a[i]?+?"?")
????}
????//?這里我們使用range來計算一個切片的所有元素和
????//?這種方法對數(shù)組也適用
????nums?:=?[]int{2,?3,?4}
????sum?:=?0
????for?_,?num?:=?range?nums?{
????????sum?+=?num
????}
????fmt.Println("sum:",?sum)
????//?range?用來遍歷數(shù)組和切片的時候返回索引和元素值
????//?如果我們不要關心索引可以使用一個下劃線(_)來忽略這個返回值
????//?當然我們有的時候也需要這個索引
????for?i,?num?:=?range?nums?{
????????if?num?==?3?{
????????????fmt.Println("index:",?i)
????????}
????}
????//?使用range來遍歷字典的時候,返回鍵值對。
????kvs?:=?map[string]string{"a":?"apple",?"b":?"banana"}
????for?k,?v?:=?range?kvs?{
????????fmt.Printf("%s?->?%s\n",?k,?v)
????}
????// range函數(shù)用來遍歷字符串時,返回Unicode代碼點。
????//?第一個返回值是每個字符的起始字節(jié)的索引,第二個是字符代碼點,
????//?因為Go的字符串是由字節(jié)組成的,多個字節(jié)組成一個rune類型字符。
????for?i,?c?:=?range?"go"?{
????????fmt.Println(i,?c)
????}
}
sum:?9
index:?1
a?->?apple
b?->?banana
0?103
1?111
- Go數(shù)組排序
Go 分別提供了sort.Float64s() ?sort.Strings() ?sort.Ints() 對不同類型的數(shù)組進行排序,默認是升序。
降序需要使用sort.Reverse。
package?mainimport?("fmt""sort")
func?main()?{
?
???arrayInt?:=?[]int{3,?1,?2,?5,?4}
?
???arrayFloat?:=?[]float64{3.2,?1.8,?1.9,?2.2,?4.3}
?
???arrayString?:=?[]string{"abc",?"ab",?"bc"}
?
???//?升序
????sort.Ints(arrayInt)
????sort.Float64s(arrayFloat)
????sort.Strings(arrayString)
????fmt.Println("sort?int:",?arrayInt)
????fmt.Println("sort?float:",?arrayFloat)
????fmt.Println("sort?",?arrayString)
????//?降序
????sort.Sort(sort.Reverse(sort.IntSlice(arrayInt)))
????sort.Sort(sort.Reverse(sort.Float64Slice(arrayFloat)))
????sort.Sort(sort.Reverse(sort.StringSlice(arrayString)))
????fmt.Println("After?reversed:?")
????fmt.Println("sort?int:",?arrayInt)
????fmt.Println("sort?float:",?arrayFloat)
????fmt.Println("sort?",?arrayString)
?
}
- 數(shù)組的拷貝和傳參
a. 數(shù)組是值類型
var?a?[3]inta[0]?=?10
a[1]?=?20
a[2]?=?30
b?:=?a
//b拷?了數(shù)組a中所有元素
b[0]?=?1000
a:?[10,20,30]
b:?[1000,20,30]
b. 數(shù)組是值類型,函數(shù)傳參也會拷?
package?mainimport?("fmt")func?main()?{
??var?a?[3]int
??a[0]?=?10
??a[1]?=?20
??a[2]?=?30
??
??modify(a)?
??fmt.Println(a)????//?[10,20,30]
}
func?modify(b?[3]int)?{
??b[0]?=?1000
??fmt.Println(b)????//?[1000,20,30]
??return
}
GO 切片
GO的切片是基于數(shù)組類型的一層封裝。Go 數(shù)組的長度不可改變,在特定場景中這樣的集合就不太適用,Go中提供了一種靈活,功能強悍的內置類型切片("動態(tài)數(shù)組"),與數(shù)組相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
?var?a?[]int//定義?個int類型的空切?
- 切?初始化, a[start:end]創(chuàng)建?個包括從start到end-1的切?。
)
func?main()?{
????//?初始化方法1
????a:=?[5]int{76,?77,?78,?79,?80}
????var?b?[]int?=?a[1:?4]?//基于數(shù)組a
????//?創(chuàng)建?個切?,包括元素a[1]?a[2]?a[3]
????fmt.Println(b)
????
????//?初始化方法2
????c:=[]int{6,?7,?8}?//創(chuàng)建一個數(shù)組并返回?個切?
????fmt.Println(c)
}
- 數(shù)組切片的基本操作
a. arr[start:end]:包括start到end-1(包括end-1)之間的所有元素
b. arr[start:]:包括start到arr最后?個元素(包括最后一個元素)之間的所有元素
c. arr[:end]:包括0到end-1(包括end-1)之間的所有元素
d. arr[:]:包括整個數(shù)組的所有元素
- 切?修改
)
func?main()?{
????
????//創(chuàng)建?個數(shù)組,其中[...]是編譯?確定數(shù)組的長度,darr的長度是9
???darr:=[...]int{57,?89,?90,?82,?100,?78,?67,?69,?59}
???//基于darr創(chuàng)建?個切?dslice,包括darr[2],darr[3],darr[4]三個元素
???dslice:=darr[2:5]
???fmt.Println("array?before",darr)
???for?i:=range?dslice?{
?????//對于dslice中每個元素進行+1,其實修改是darr[2],darr[3],darr[4]
????dslice[i]++
??}
?
??fmt.Println("array?after",darr)
}??????
//?array?before?[57?89?90?82?100?78?67?69?59]
//?array?after?[57?89?91?83?101?78?67?69?59]
切片是數(shù)組的引用,當兩個切片源于一個數(shù)組,改變其中一個數(shù)組,另一個數(shù)組也響應的進行的修改。
package?mainimport?("fmt")
func?main()?{
????
?numa:=[3]int{78,?79?,80}
?//創(chuàng)建?個切?,包含整個數(shù)組的所有元素
??
?nums1?:=?numa[:]
?nums2?:=?numa[:]
?fmt.Println("array?before?change?1",numa)
???
?nums1[0]=?100
??
?fmt.Println("array?after?modification?to?slice?nums1",?numa)
???
?nums2[1]=101
??
?fmt.Println("array?after?modification?to?slice?nums2",?numa)
}?
//?array?before?change?1?[78?79?80]
//?array?after?modification?to?slice?nums1?[100?79?80]
//?array?after?modification?to?slice?nums2?[100?101?80]
- 使?make創(chuàng)建切片
make為內建類型slice、map和channel分配內存。
?package?mainimport?("fmt"??)
?func?main()?{
????//[]中沒有?度?第一個5?是切片的長度,第二個?5是切片的容量
????i:=make([]int,?5,?5)
????fmt.Println(i)
?}
?//?[0?0?0?0?0]
- 切片的?度和容量
??)
?func?main()?{
?
????var?a?[]int
????a?=make([]int,?5,?10)
????a[0]?=?10
????fmt.Printf("a=%v?addr:%p?len:%d?cap:%d\n",?a,a,len(a),cap(a))???//?a=[10?0?0?0?0]?addr:0xc0000a0000?len:5?cap:10
????a=?append(a,11)
????fmt.Printf("a=%v?addr:%p?len:%d?cap:%d\n",?a,a,len(a),cap(a))??//a=[10?0?0?0?0?11]?addr:0xc00009e000?len:6?cap:10
????for?i:=0;?i?8;i++?{
??????a=?append(a,?i)
??????fmt.Printf("a=%v?addr:%p?len:%d?cap:%d\n",?a,a,len(a),cap(a))
??????//?a=[10?0?0?0?0?11?0]?addr:0xc00009e000?len:7?cap:10
??????//?a=[10?0?0?0?0?11?0?1]?addr:0xc00009e000?len:8?cap:10
??????//?a=[10?0?0?0?0?11?0?1?2]?addr:0xc00009e000?len:9?cap:10
??????//?a=[10?0?0?0?0?11?0?1?2?3]?addr:0xc00009e000?len:10?cap:10
??????//?a=[10?0?0?0?0?11?0?1?2?3?4]?addr:0xc0000a4000?len:11?cap:20
??????//?a=[10?0?0?0?0?11?0?1?2?3?4?5]?addr:0xc0000a4000?len:12?cap:20
??????//?a=[10?0?0?0?0?11?0?1?2?3?4?5?6]?addr:0xc0000a4000?len:13?cap:20
??????//?a=[10?0?0?0?0?11?0?1?2?3?4?5?6?7]?addr:0xc0000a4000?len:14?cap:20
????}
????//?觀察切片的擴容操作?擴容的策略是翻倍擴容
????a?=?append(a,1000)
????fmt.Printf("a=%v?addr:%p?len:%d?cap:%d\n",?a,a,len(a),cap(a))
????//?a=[10?0?0?0?0?11?0?1?2?3?4?5?6?7?1000]?addr:0xc0000200a0?len:15?cap:20
?}
例子2:
package?mainimport?("fmt")
func?main()?{
?????
??fruitarray?:=[...]string{
???
????"apple",?"orange",?"grape",
??????
????"mango",?"water?melon",
????
????"pine?apple",?"chikoo"}
????
??fruitslice:=fruitarray[1:3]//長度是2,容量is?6
?????
??fmt.Printf("length?of?slice?%d?capacity?%d",len(fruitslice),?cap(fruitslice))
}??
//?length?of?slice?2?capacity?6
- 切片再切片
)
func?main()?{
?????
??fruitarray:=[...]string{
????
????"apple",?"orange",?"grape",?"mango",
????????
????"water?melon",?"pine?apple",?"chikoo"}
??????
????fruitslice:=fruitarray[1:3]
????//長度是2,?容量是6
?????
????fmt.Printf("length?of?slice?%d?capacity?%d\n",len(fruitslice),?cap(fruitslice))
????//再重新進行切?,不能?于數(shù)組fruitarray的?度,否則越界
????
????fruitslice?=?fruitslice[:cap(fruitslice)]
????????
????fmt.Println("After?re-slicing?length?is",len(fruitslice),?"and?capacity?is",cap(fruitslice))
???????????
}
//?length?of?slice?2?capacity?6
//?After?re-slicing?length?is?6?and?capacity?is?6
- append 操作
)
func?main()?{
?cars:=[]string{"Ferrari",?"Honda",?"Ford"}
??//?度和容量都等于3
??fmt.Println("cars:",?cars,?"has?old?length",len(cars),?"and?capacity",?cap(cars))
??????????
??cars=append(cars,?"Toyota")
??//容量等于6
???
??fmt.Println("cars:",?cars,?"has?new?length",len(cars),?"and?capacity",?cap(cars))
}
//?cars:?[Ferrari?Honda?Ford]?has?old?length?3?and?capacity?3
//?cars:?[Ferrari?Honda?Ford?Toyota]?has?new?length?4?and?capacity?6
a. append?個切?
package?mainimport?("fmt")
func?main()?{
????
??veggies:=[]string{"potatoes","tomatoes","brinjal"}
??????????
??fruits?:=[]string{"oranges","apples"}
??//fruits后?的3個點表示展開fruits切?成?個元素
??????
??food:=?append(?veggies,?fruits...)
??fmt.Println("food:",food)
}
//??food:?[potatoes?tomatoes?brinjal?oranges?apples]
- 空切片
??)
??func?main()?{
????//定義names是?個空切?,?度和容量都等于0
????//不能對空切?進行訪問,否則panic
???
?var?names?[]string
????
?if?names?==?nil?{
?????
?????fmt.Println("slice?is?nil?going?to?append")
??????
?????names?=?append(names,?"John",?"Sebastian",?"Vinay")
????????????
?????fmt.Println("names?contents:",names)???
?}
}
- 切片傳參
)//在函數(shù)內部修改numbers切?的值
func?subtactOne(numbers?[]int)?{
????for?i:=?range?numbers?{
??????numbers[i]-=2
????}
}
func?main()?{
????nos:=[]int{8,?7,?6}
????fmt.Println("slice?before?function?call",?nos)
????subtactOne(nos)
????//nos修改?效了,說明切片是引?類型
????fmt.Println("slice?after?function?call",?nos)
}
//?slice?before?function?call?[8?7?6]
//?slice?after?function?call?[6?5?4]
- 切片深拷貝
)
func?main()?{
???//?當元素數(shù)量超過容量
???//?切片會在底層申請新的數(shù)組
???slice?:=?make([]int,?5,?5)
???slice1?:=?slice
???slice?=?append(slice,?1)
???slice[0]?=?1
???fmt.Println(slice)//[1?0?0?0?0?1]
???fmt.Println(slice1)//[0?0?0?0?0]
???//?copy?函數(shù)提供深拷貝功能
???//?但需要在拷貝前申請空間
???slice2?:=?make([]int,?4,?4)
???slice3?:=?make([]int,?5,?5)
???fmt.Println(copy(slice2,?slice))//4
???fmt.Println(copy(slice3,?slice))//5
???fmt.Println(slice2)//?[1?0?0?0]
???fmt.Println(slice3)//?[1?0?0?0?0]
???slice2[1]?=?2
???slice3[1]?=?3
???fmt.Println(slice)//[1?0?0?0?0?1]
???fmt.Println(slice2)//[1?2?0?0]
???fmt.Println(slice3)//[1?3?0?0?0]
}
- 切片遍歷
a[0]?=?10
a[1]?=?20
a[2]?=?30
B?:=?a[:]
for?index,?val?:=?range?b?{
}
//和數(shù)組遍歷是?樣的
- new?于各種類型的內存分配,new返回是?個指針
Go 變量和內存地址
每個變量都有內存地址,可以說通過變量來操作對應?大?小的內存 。注意:通過&符號可以獲取變量的地址。
普通變量存儲的是對應類型的值,這些類型就叫值類型 例: var a int32。
指針類型的變量存儲的是一個地址,所以?叫指針類型或引用類型, 在定義時,前方加*就變?yōu)橐妙愋?#xff0c;var a *int32, a中存儲的是一個地址,我們稱為引用類型或者指針類型。
package?mainimport?("fmt")
func?main()?{
??var?a?int32
??a?=?100
??fmt.Printf("%d\n",?a)
??fmt.Printf("%p\n",?&a)
??b:=255
?????
??var?c?*int?=?&b
???????
??fmt.Printf("Type?of?c?is?%T\n",?c)
??????????
??fmt.Println("address?of?b?is",?c)
}
//?100
//?0xc00001608c
//?Type?of?a?is?*int
//?address?of?b?is?0xc00009a008
- 指針類型變量的默認值為nil,也就是空地址
)
func?main()?{
??a?:=?25?
??var?b?*int?
??if?b?==?nil?{
????fmt.Println("b?is",?b)?
????b?=?&a
????fmt.Println("b?after?initialization?is",?b)
??}
}
//?b?is?
//?b?after?initialization?is?0xc0000a2008
- 如果操作指針變量指向的地址里面的值呢?
注意:通過* 符號可以獲取指針變量指向的變量。
package?mainimport?("fmt")
func?main()?{
??b?:=?255
??a?:=?&b
????
??fmt.Println("address?of?b?is",?a)
????????
??fmt.Println("value?of?b?is",*a)
}
//?address?of?b?is?0xc00009a008
//?value?of?b?is?255
- 通過指針修改變量的值
)
func?main()?{
??b?:=?255
??a?:=?&b
????
??fmt.Println("address?of?b?is",?a)
??fmt.Println("value?of?b?is",?*a)
??*a++
??fmt.Println("new?value?of?b?is",b)
}
//?address?of?b?is?0xc00009a008
//?value?of?b?is?255
//?new?value?of?b?is?256
- 指針變量傳參
)?
func?change?(val?*int){
??*val?=?55
}
func?main()?{
??a?:=?255
??fmt.Println("value?of?a?before?function?call?is",a)
??b?:=?&a
??change(b)
??fmt.Println("value?of?a?after?function?call?is",?a)
}
//?value?of?a?before?function?call?is?255
//?value?of?a?after?function?call?is?55
//?例子2
func?change?(arr?*[3]int){
??(*arr)[0]?=?90
}
func?main()?{
??a:=[3]int{89,?90,?91}
??change(&a)
??fmt.Println(a)
}
//?[90?90?91]
對比?切片傳參注意:切片是引用類型!!
func?change?(arr?[]int){
??arr[0]?=?90
}
func?main()?{
??a:=[3]int{89,?90,?91}
??change(a[:])
??fmt.Println(a)
}
//?[90?90?91]
//?make?來分配引?類型的內存,?如?map、slice以及channel?,new?來分配除引用類型的所有其他類型的內存,?如?int、數(shù)組等
?
- 值拷?和引?拷?
?)
?func?main()?{
?????//?值拷貝
?????var?a?int?=?100
?????b?:=?a
?????
????//?引用拷貝
?????var?a?int?=?100
?????var?b?*int?=?&a
?????var?c?*int?=?b
?????*c?=?200
?}
Go Map 類型
map類型是?個key-value的數(shù)據(jù)結構。注意:map必須初始化才能使?,否則panic。
map類型的變量默認初始化為nil,需要使用make分配map內存。
//var?a?map[key的類型]value類型?????
var?a?map[string]int
var?b?map[int]string
var?c?map[float32]string
package?mainimport?("fmt"
)?
func?main()?{??
??var?a?map[string]int
??if?a?==?nil?{
????fmt.Println("map?is?nil.?Going?to?make?one.")
????a?=?make(map[string]int)??
??}
}
- map插入操作
)?
func?main()?{??
??a?:=?make(map[string]int)
??a["steve"]?=?12000
??a["jamie"]?=?15000
??a["mike"]?=?9000
??fmt.Println("a?map?contents:",?a)
}
//?a?map?contents:?map[jamie:15000?mike:9000?steve:12000]
- map 聲明方式二, 通過key訪問map中的元素
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??fmt.Println("a?map?contents:",?a)
}
- 如何判斷map指定的key是否存在? value, ok := map[key]
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??b?:=?"joe"
??value,?ok?:=?a[b]
??if?ok?==?true?{
????fmt.Println("Salary?of",?b,?"is",?value)
??}?else?{
????fmt.Println(b,"not?found")
??}
??fmt.Println("a?map?contents:",?a)
}
//?joe?not?found
//?a?map?contents:?map[jamie:15000?mike:9000?steve:12000]
- map遍歷操作
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??for?key,?value:=?range?a?{
??????fmt.Printf("personSalary[%s]?=?%d\n",?key,?value)
??}
}
//?personSalary[steve]?=?12000
//?personSalary[jamie]?=?15000
//?personSalary[mike]?=?9000
- map刪除元素
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??delete(a,?"steve")
??fmt.Println("map?after?deletion",?a)
}
//?map?after?deletion?map[jamie:15000?mike:9000]
- map的?度 ?len(a)
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??fmt.Println("length?is",?len(a))
}
//?length?is?3
- map是引?類型
)?
func?main()?{??
??a?:=?map[string]int?{
????"steve":?12000,
????"jamie":?15000,
??}
??a["mike"]?=?9000
??b?:=?a
??b["mike"]?=?18000
??fmt.Println("a?map?changed",?a)
}
//?a?map?changed?map[jamie:15000?mike:18000?steve:12000]
- 默認情況下,map并不是按照key有序進?遍歷的 ,map按照key進行排序,遍歷 。
)
func?main()?{
???var?a?map[string]int?=?make(map[string]int,?10)
???for?i?:=?0;?i?10;?i++?{
?????key?:=?fmt.Sprintf("key%d",?i)
?????a[key]?=?i
???}
???var?keys?[]string
???for?key,?_?:=?range?a?{
?????keys?=?append(keys,?key)
???}
???sort.Strings(keys)
???for?_,?key?:=?range?keys?{
?????fmt.Printf("key:%s=%d\n",?key,?a[key])
???}
}
?
//?key:key0=0
//?key:key1=1
//?key:key2=2
//?key:key3=3
//?key:key4=4
//?key:key5=5
//?key:key6=6
//?key:key7=7
//?key:key8=8
//?key:key9=9
- map類型的切?
??)
??func?main()?{
????var?mapSlice?[]map[string]int
????mapSlice?=?make([]map[string]int,?5)
????fmt.Println("before?map?init")
????for?index,?value?:=?range?mapSlice?{
????????fmt.Printf("index:%d?value:%v\n",?index,?value)
????}
??
????mapSlice[0]?=?make(map[string]int,?10)
????mapSlice[0]["a"]?=?1000
????mapSlice[0]["b"]?=?2000
????mapSlice[0]["c"]?=?3000
????mapSlice[0]["d"]?=?4000
????mapSlice[0]["e"]?=?5000
????fmt.Println("after?map?init")
????for?index,?value?:=?range?mapSlice?{
??????fmt.Printf("index:%d?value:%v\n",?index,?value)
????}
??}
??
//?before?map?init
//?index:0?value:map[]
//?index:1?value:map[]
//?index:2?value:map[]
//?index:3?value:map[]
//?index:4?value:map[]
//?after?map?init
//?index:0?value:map[a:1000?b:2000?c:3000?d:4000?e:5000]
//?index:1?value:map[]
//?index:2?value:map[]
//?index:3?value:map[]
//?index:4?value:map[]
Go 面向對象編程
- struct聲明和定義
Go中?向對象是通過struct來實現(xiàn)的, struct是用戶?定義的類型 , 注意:type是?來定義?種類型
?type?User?struct?{?????Username??string
?????Sex???????string
?????Age???????int
?????AvatarUrl?string
?}
初始化 方法分為兩種:
方法一:注意:使?變量名+?‘.’?+?字段名訪問結構體中的字段
var?user?User
user.Age?=?18
user.Username?=?“user01”
user.Sex?=?“男”
user.AvatarUrl?=?“http://my.com/xxx.jpg"
方法二:
var?user?User?=?User?{
??“Username”?:?“user01”,
??“Age”:?18,
??“Sex”:?“男”,
??“AvatarUrl”:?“http://my.com/xxx.jpg”,
}
更簡單的寫法:
?user?:=?User?{
???“Username”?:?“user01”,
???“Age”:?18,
???“Sex”:?“男”,
???“AvatarUrl”:?“http://my.com/xxx.jpg”,
}
- struct初始化的默認值是什么?
??fmt.Printf(“%#v\n”,?user)
- 結構體類型的指針
注意:&User{}和new(User) 本質上是?樣的,都是返回一個 結構體的地址
package?mainimport?("fmt")?
func?main()?{??
??var?user?*User?=?&User{}?????
??fmt.Printf(“%p?%#v\n”,?user)
??//?直接初始化:
??var?user?*User?=?&User?{
????Username?:?“user01”,
????Age:?18,
????Sex:?“男”,
????AvatarUrl:?“http://my.com/xxx.jpg”,
??}
??//?或者使用new
??var?user?User?=?new(User)
????user.Age?=?18
????user.Username?=?“user01”
????user.Sex?=?“男”
????user.AvatarUrl?=?“http://my.com/xxx.jpg"
??}
- 結構體的內存布局: 占??段連續(xù)的內存空間
結構體沒有構造函數(shù), 必要時需要??實現(xiàn)
匿名字段: 即沒有名字的字段 ? ? ?注意:匿名字段默認采用類型名作為 字段名
?????Username??string
?????Sex???????string
?????Age?int
?????AvatarUrl?string
?}
?
type?User?struct?{
????Username??string
????Sex???????string???
????Age?int
????AvatarUrl?string
????int
????string
}
- 結構體嵌套
?????City???????????string
?????Province???????string
?}
type?User?struct?{
?????Username??string
?????Sex???????string
?????Age?int
?????AvatarUrl?string
?????address?*Address
}?????
func?main?()?{
??user?:=?&User?{
????Username:?'user01',
????Sex:?'man',
????address:?&Address?{
??????Province:?'beijing',
??????City:?'beijing',
????},
??}
}
- 匿名結構體
第二種方式 先在結構體里面找Provice以及City,如果結構體里面沒有,則在匿名結構體里面找,
type?Address?struct?{?????City???????????string
?????Province???????string
}
type?User?struct?{
????Username??string
????Sex???????string
????Age?int
????AvatarUrl?string
????*Address
}
func?main?()?{
????var?user?User
????user.Username?=?'user01'
????user.Sex?=?'man'
????//?第一種方式
????user.Address?=?&Address{
???????Provice:?'bj',
???????City:?'bj'
????}
???//?第二種方式
???user.Province?=?'bj01'
???user.City?=?'bj01'
}
- 匿名結構體的沖突解決 使用結構體的字段,如果結構體字段有值,則使用結構體,如果沒有則使用匿名結構體的字段 如果兩個匿名結構體都有相同的字段,當訪問這個相同字段時候,要指定訪問那個匿名結構體的字段
)
type?Address?struct?{
??City???string
??Province?string
??CreateTime?string
}
type?Email?struct?{
??Account??string
??CreateTime??string
}
type?User?struct?{?
??Username??string
??Sex???????string
??Age?int
??AvatarUrl?string
??*Address
??CreateTime?string
}
func?main?(){
??var?user?User
??user.Username?=?"user01"
??user.Sex?=?"man"
??user.City?=?"bj"
??user.Address?=?new(Address)
??user.Email?=?new(Email)
??user.Address.City?="bj01"
??user.Address.CreateTime?="001"
??user.Email.CreateTime?=?"002"
??fmt.Println(?user.Email.CreateTime,?user.Address.CreateTime)
}
??
- 字段可?性,?寫表示可公開訪問,?寫表示私有
????Username?string
????Sex?string
????Age?int
????avatarUrl?string?//?私有
????CreateTime?string
}
- tag是結構體的元信息,可以在運行的時候通過反射的機制讀取出來 字段類型后?,以反引號括起來的 key-value結構的字符串,多個tag 以逗號隔開。
????Username??string???`json:”username”,db:”user_name”`
????Sex???????string???`json:”sex”`???
????Age???????int??????`json:”age”`
????avatarUrl?string
????CreateTime?string
}
Go 方法的定義
和其他語?不?樣,Go的?法采?另外?種?式實現(xiàn)
Go的?法是在函數(shù)前?加上一個接受者,這樣編譯器就知道這個?法屬于哪個類型了
- 可以為當前包內定義的任何類型增加方法
- 函數(shù)和方法的區(qū)別: 函數(shù)不屬于任何類型,?法屬于特定的類型
- 指針類型作為接受者
- 指針類型和值類型作為接受者的區(qū)別
type?People?struct?{
??Name??string
??Country?string
}
func?(p?People)?Print()?{
??fmt.Println("name=%s?country=%s\n",p.Name,?p.Country)
}
func?(p?People)?Set(name?string,?country?string)?{
??p.Name?=?name
??p.Country?=?country
}
func?main()?{
??var?p1?People?=?People?{
????Name:?"people01",
????Country:?"china",
??}
??p1.Print()??//??people01?china
??p1.Set("people02","english")
??p1.Print()?//?不變?p是實例的拷貝???people01?china
}
?
?
指針類型:
type?People?struct?{
??Name??string
??Country?string
}
func?(p?People)?Print()?{
??fmt.Println("name=%s?country=%s\n",p.Name,?p.Country)
}
//?值類型
func?(p?People)?Set(name?string,?country?string)?{
??p.Name?=?name
??p.Country?=?country
}
//?引用類型
func?(p?*People)?SetV2(name?string,?country?string)?{
??p.Name?=?name
??p.Country?=?country
?}
func?main()?{
??var?p1?People?=?People?{
????Name:?"people01",
????Country:?"china",
??}
??p1.Print()??//??people01?china
??p1.Set("people02","english")
??p1.Print()?//?不變?p是實例的拷貝???people01?china
??(&p1).SetV2("people02","english")或?語法糖: p1.SetV2("people02","english")
??p1.Print()?//?變了?people02?english
}
?
- 什么時候用值類型/指針類型作為接受者?
a. 需要修改接受者中的值的時候 b. 接受者是?對象的時候,副本拷貝代價?較大 c. ?般來說,通常使?指針類型作為接受者
- 匿名結構體與繼承
通過組合 和 匿名字段實現(xiàn)的繼承,方法的沖突解決和匿名字段的沖突解決一致,都是通過指定對應的實例的方法解決
type?Anaimal?struct?{??Name??string
??Sex?string
}
func?(a?*Anaimal)?Talk()?{
??fmt.Println(a.Name)
}
type?Dog?struct?{
??Feet?string
??*Anaimal
}
func?(d?*Dog)?Eat?()?{
??fmt.Println("dog?is?eat")
}
func?main?()?{
??var?d?*Dog?=?&Dog{
????Feet:?"Four?Feet",
????Anaimal:?&Anaimal?{
??????Name:?"dog",
??????Sex:?"xiong",
????},
??}
??d.Name?=?"dog"
??d.Sex?=?"xiong"
??d.Eat()
??d.Talk()
}
- 多重繼承與沖突解決
?????Name?string
?}
?type?Father?struct?{
?????Name?string
?}
?type?People?struct?{
????Sex???????string
????Age?int
????*Mother
????*Father
?}
- 結構體與json序列列化
)
type?Student?struct?{
???Id???string
???Name?string
???Sex??string
}
type?Class?struct?{
???Name?????string
???Count????int
???Students?[]*Student
}
var?rawJson?=?`
{"Name":"101","Count":0,"Students":[{"Id":"0","Name":"stu0","Sex":"man"},{"Id":"1","Name":"stu1","Sex":"man"},{"Id":"2","Name":"stu2","Sex":"man"},{"Id":"3","Name":"stu3","Sex":"man"},{"Id":"4","Name":"stu4","Sex":"man"},{"Id":"5","Name":"stu5","Sex":"man"},{"Id":"6","Name":"stu6","Sex":"man"},{"Id":"7","Name":"stu7","Sex":"man"},{"Id":"8","Name":"stu8","Sex":"man"},{"Id":"9","Name":"stu9","Sex":"man"}]}
`
func?main()?{
???c?:=?&Class{
??????Name:??"101",
??????Count:?0,
???}
???for?i?:=?0;?i?10;?i++?{
??????stu?:=?&Student{
?????????Name:?fmt.Sprintf("stu%d",?i),
?????????Sex:??"man",
?????????Id:???fmt.Sprintf("%d",?i),
??????}
??????c.Students?=?append(c.Students,?stu)
???}
???data,?err?:=?json.Marshal(c)
???if?err?!=?nil?{
??????fmt.Println("json?marshal?failed")
??????return
???}
???fmt.Printf("json:%s\n",?string(data))
???//json反序列化
???fmt.Println("unmarshal?result?is?\n\n")
???var?c1?*Class?=?&Class{}
???err?=?json.Unmarshal([]byte(rawJson),?c1)
???if?err?!=?nil?{
????????fmt.Println("unmarhsal?failed")
????????return
???}
???fmt.Printf("c1:%#v\n",?c1)
???for?_,?v?:=?range?c1.Students?{
????????fmt.Printf("stu:%#v\n",?v)
???}
}
推薦閱讀
(點擊標題可跳轉閱讀)
RxJS入門
一文掌握Webpack編譯流程
一文深度剖析Axios源碼
Javascript條件邏輯設計重構
Promise知識點自測你不知道的React?Diff你不知道的GIT神操作程序中代碼壞味道(上)
程序中代碼壞味道(下)
學習Less,看這篇就夠了
一文掌握GO語言實戰(zhàn)技能(一)
一文掌握Linux實戰(zhàn)技能-系統(tǒng)管理篇
一文掌握Linux實戰(zhàn)技能-系統(tǒng)操作篇
一文達到Mysql實戰(zhàn)水平
一文達到Mysql實戰(zhàn)水平-習題答案
從表單抽象到表單中臺
vue源碼分析(1)- new Vue
實戰(zhàn)LeetCode 系列(一) (題目+解析)
一文掌握Javascript函數(shù)式編程重點
實戰(zhàn)LeetCode - 前端面試必備二叉樹算法
一文讀懂 React16.0-16.6 新特性(實踐 思考)
阿里、網(wǎng)易、滴滴、今日頭條、有贊.....等20家面試真題
30分鐘學會 snabbdom 源碼,實現(xiàn)精簡的 Virtual DOM 庫
覺得本文對你有幫助?請分享給更多人
關注「React中文社區(qū)」加星標,每天進步
總結
以上是生活随笔為你收集整理的go int 转切片_一文掌握GO语言实战技能(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机 网络访问保护,开启win2008
- 下一篇: 数据结构之结构体复习