真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Go學(xué)習(xí)之路:更多類型:struct、slice和映射(DAY2)-創(chuàng)新互聯(lián)

文章目錄
    • 前引
    • 更多類型:struct、slice 和映射
      • 1、指針
      • 2.1、結(jié)構(gòu)體/結(jié)構(gòu)體命名(一)
      • 2.2、結(jié)構(gòu)體/對象訪問、指針訪問、初始化規(guī)則(二)
      • 3、數(shù)組
      • 4.1、切片/初始化切片
      • 4.2、切片/切片引用數(shù)組
      • 4.3、切片/切片的length和capacity
      • 4.4、切片/Nil切片
      • 4.5、切片/設(shè)置為二維切片/切片添加元素
      • 5、Range
      • 6.1、映射/map的初始化
      • 6.2、映射/映射的基本操作
      • 7.1、函數(shù)/函數(shù)值
      • 7.2、函數(shù)/函數(shù)閉包

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比永城網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式永城網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋永城地區(qū)。費(fèi)用合理售后完善,十余年實體公司更值得信賴。
前引

周天辣 昨天全員核酸沒有陽性 如果再有兩天陰性的話 就有機(jī)會樓棟能解封啦 最好的情況希望能出現(xiàn) 周二能回去!

在寢室里閑著也是閑著 還是學(xué)一下go吧 把剩下的基礎(chǔ)的給學(xué)完
希望好運(yùn)伴隨!
希望未來順利


更多類型:struct、slice 和映射
1、指針

go語言中仍舊保持了有指針的特性 這個還是非常欣慰的
準(zhǔn)確來說應(yīng)該和c/c++差別并不大 唯一的差別是不能進(jìn)行指針運(yùn)算

下面是例子
111.go

package main

import "fmt"

func main() {i, j := 1, 2
	p := &i
	fmt.Println(*p, i, j)
	p = &j
	fmt.Println(*p, i, j)
	*p = 3
	fmt.Println(*p, i, j)
}

運(yùn)行效果
在這里插入圖片描述


2.1、結(jié)構(gòu)體/結(jié)構(gòu)體命名(一)

命名方式相比于c語言有所不一樣 其他的基本大致相同
type name struct

然后從這里我自己去搜了10分鐘的資料
發(fā)現(xiàn)go語言的內(nèi)存分配和c++ 完全不一樣
第一點(diǎn) c++需要自己手動解決內(nèi)存分配問題 而go語言是自動回收
第二點(diǎn) go語言會自動分析該對象是否是需要分配內(nèi)存 決定于內(nèi)存逃逸行為 go語言的內(nèi)存分析我剛剛又花了20分鐘看了一下 發(fā)現(xiàn)不像是c++那樣 什么對象是動態(tài)分配的 什么是靜態(tài)分配(在棧中)定義的時候 自己都清楚 而是取決于當(dāng)前對象是否能被外部引用 go語言還是偏向于分配棧對象的 但是對于沒有辦法確認(rèn)是否會被外部引用時 只能放于堆中 用GC來管理

關(guān)于內(nèi)存分配問題 這個后面還要花很多事情去研究研究 下面寫了很多 來看究竟結(jié)構(gòu)體的內(nèi)存分配情況 以及結(jié)構(gòu)體的初始化


111.go

package main

import "fmt"

type Node struct {val int
	next *Node
}

var global_ptr *Node

func PtrGo() {global_ptr = &Node{}
	global_ptr.val = -1
}

func main() {// 初始化1
	var dummynode1 Node
	dummynode1.val = -1 //初始化為0后 再賦值
	ptr1 := &dummynode1
	fmt.Printf("%d %p %s%p %s%p %s\n", dummynode1.val, dummynode1.next, "ptr addr:", &ptr1, "struct addr:", ptr1 , "way 3")

	//初始化2
	dummynode2 := Node{-1, nil}
	ptr2 := &dummynode2
	fmt.Printf("%d %p %s%p %s%p %s\n", dummynode2.val, dummynode2.next, "ptr addr:", &ptr2, "struct addr:", ptr2, "way 3")

	//初始化3
	dummynode3 := new(Node)
	dummynode3.val = -1
	ptr3 := dummynode3
	fmt.Printf("%d %p %s%p %s%p %s\n", dummynode3.val, dummynode3.next, "ptr addr:", &ptr3, "struct addr:", ptr3, "way 3")

	//初始化4
	PtrGo()
	fmt.Printf("%d %p %s%p %s%p %s\n", global_ptr.val, global_ptr.next, "ptr addr:", &global_ptr, "struct addr:", global_ptr, "way 4")
}

運(yùn)行效果
在這里插入圖片描述


2.2、結(jié)構(gòu)體/對象訪問、指針訪問、初始化規(guī)則(二)

結(jié)構(gòu)體不管是指針還是直接對象訪問結(jié)構(gòu)體內(nèi)部值 都是通過.符號來訪問 不用指針->來訪問了
第二個 初始化規(guī)則 上面的方式已經(jīng)寫完了初始化的方式

111.go

package main

import "fmt"

type Node struct {val int
	next *Node
}

func main() {var dummynode1 = Node{-1, nil}
	fmt.Println(dummynode1)

	var dummynode2 = Node{val : -1}
	fmt.Println(dummynode2)

	var dummynode3 = Node{next : nil}
	dummynode3.val = -1
	fmt.Println(dummynode3)

	dummynode4 := Node{-1, nil}
	fmt.Println(dummynode4)

	dummynode5 := new(Node)
	dummynode5.val = -1
	fmt.Println(*dummynode5)
}

運(yùn)行效果
在這里插入圖片描述


3、數(shù)組

構(gòu)造方式和c語言類似 聲明方式仍舊是golang化
簡單的例子應(yīng)用

package main

import "fmt"

func main() {var strs [2]string
	strs[0] = "Hello,"
	strs[1] = "World!"
	fmt.Println(strs[0], strs[1])
}

運(yùn)行效果
在這里插入圖片描述


數(shù)組的初始化辦法
下面有這幾種

111.go

package main

import (
	"fmt"
)

func main() {var nums1 [10]int = [10]int {1, 2, 3}
	for i := 0; i< 10; i++ {fmt.Printf("%d ", nums1[i])
	}
	fmt.Println()

	var nums2 = [10]int{1, 2, 3}
	for _, num := range nums2 {fmt.Printf("%d ", num)
	}
	fmt.Println()

	nums3 := [...]int{1, 2, 3}
	for _, num := range nums3 {fmt.Printf("%d ", num)
	}
	fmt.Println()

	nums4 := [10]int{0:1, 1:2, 2:3}
	for _, num := range nums4 {fmt.Printf("%d ", num)
	}
	fmt.Println()

	var nums5 [10]int
	nums5[0] = 1
	nums5[1] = 2
	nums5[2] = 3
	for _, num := range nums5 {fmt.Printf("%d ", num)
	}
	fmt.Println()
}

運(yùn)行效果
在這里插入圖片描述


4.1、切片/初始化切片

切片在還沒有學(xué)習(xí)Go語言的時候就聽說了其鼎鼎大名
所以我們還是來接觸一下

slice的底層實現(xiàn) 本質(zhì)還是根據(jù)的數(shù)組的底層 可以說用指針來表示數(shù)組的開始位置
三個數(shù)據(jù)結(jié)構(gòu)支持slice指針 size capacity
我認(rèn)為如果是從數(shù)組切分出來的切片 不擴(kuò)容 此時開銷是最小的
但是如果要append元素 此時可以將其看作是c++ vector本質(zhì)上擴(kuò)容的機(jī)制還是另外申請容量


切片初始化的方法很多 為了后面使用起來更得心應(yīng)手 還是挨個挨個列出來吧

111.go

package main

import (
	"fmt"
)

func main() {//初始化1 剛開始為空切片nil
	slice1 := []int{}
	fmt.Println("before append, length:", len(slice1), ", capacity:", cap(slice1))
	for i := 0; i< 10; i++ {slice1 = append(slice1, i)
	}
	fmt.Println("after append 10 elems, length:", len(slice1), ", capacity:", cap(slice1))
	for _, num := range slice1 {fmt.Printf("%d ", num)
	}
	fmt.Println("\n")

	nums2 := [10]int {1, 2, 3, 4, 5}
	slice2 := nums2[:4] //初始化2 左閉右開 0 - 3 size 4 cap 10
	slice3 := nums2[1:] //初始化3 左閉右開 1 - 10 size 9 cap 9
	slice4 := nums2[0:4:5] //初始化4 左閉右開 0 - 3 size 4 cap 5(5 - 0)
	slice5 := nums2[:] //初始化5 左閉右開 0 - 10 size 10 cap 10
	fmt.Println("slice2 length:", len(slice2), ", capacity:", cap(slice2))
	fmt.Println("slice3 length:", len(slice3), ", capacity:", cap(slice3))
	fmt.Println("slice4 length:", len(slice4), ", capacity:", cap(slice4))
	fmt.Println("slice5 length:", len(slice5), ", capacity:", cap(slice5))

	slice6 := make([]int, 0, 10) //初始化6 size 0 cap 10
	var slice7 = make([]int, 0, 10) // 初始化7 size 0 cap 10
	var slice8[]int = make([]int, 0, 10) // 初始化8 size 0 cap 10
	fmt.Println("slice6 length:", len(slice6), ", capacity:", cap(slice6))
	fmt.Println("slice7 length:", len(slice7), ", capacity:", cap(slice7))
	fmt.Println("slice8 length:", len(slice8), ", capacity:", cap(slice8))
}

運(yùn)行效果
在這里插入圖片描述


4.2、切片/切片引用數(shù)組

切片本質(zhì)上就是指向底層的數(shù)組 可以是一開始就生成切片對象 也可以是生成了數(shù)組后 再在切片上面切
如果剛開始切片是基于數(shù)組 那么修改切片 本質(zhì)就是修改數(shù)組 數(shù)組和切片共享的是同一塊內(nèi)存
而如果當(dāng)切片append擴(kuò)容后 超過了之前的切片的capacity 此時就會像vector一樣 另外找一塊內(nèi)存地址 并且將當(dāng)前的內(nèi)容復(fù)制過去 此時切片其實本質(zhì)和之前的數(shù)組就已經(jīng)沒關(guān)系了 下面例子可以很清晰的表示


111.go

package main

import (
	"fmt"
)

func main() {nums := [...]int {1, 2, 3, 4, 5}
	slice := nums[:]
	fmt.Println("before append, slice length:", len(slice), ", capacity:", cap(slice))
	fmt.Println("before modify:")
	for index, num := range nums {fmt.Printf("nums2[%d]:%d slice[%d]:%d\n", index, num, index, slice[index])
	}


	for i := 0; i< len(nums); i++ {slice[i] = i + 100
	}
	fmt.Println("after modify:")
	for index, num := range nums {fmt.Printf("nums2[%d]:%d slice[%d]:%d\n", index, num, index, slice[index])
	}

	slice = append(slice, 0)
	fmt.Println("after append, slice length:", len(slice), ", capacity:", cap(slice))
	for i := 0; i< 5; i++ {slice[i] = i + 10
	}
	for index, num := range nums {fmt.Printf("nums2[%d]:%d slice[%d]:%d\n", index, num, index, slice[index])
	}
}

運(yùn)行效果
在這里插入圖片描述


4.3、切片/切片的length和capacity

切片的length表示 當(dāng)前切片中實際存在的長度
切片的cap表示 當(dāng)前切片可擴(kuò)容的長度

切片如果基于 cap 可以擴(kuò)容 當(dāng)length == cap時 擴(kuò)容則是2倍擴(kuò)容
擴(kuò)容底層有機(jī)制 后面我再詳細(xì)看看

但是如果切片基于其他切片 則cap大只能是其他切片的cap 無法額外分配內(nèi)存擴(kuò)容


獲取切片的length是由len()獲取 capacity是由cap()獲取


4.4、切片/Nil切片

如果是空切片 例如用var slice1 []int生成切片
則為Nil切片 切片僅僅能和Nil切片作比較 不能與其他切片做比較

111.go

package main

import "fmt"

func main() {var slice1 []int
	if slice1 == nil {fmt.Println("Nil Slice")
	} else {fmt.Println("Non-Nil Slice")
	}
}

運(yùn)行效果
在這里插入圖片描述


4.5、切片/設(shè)置為二維切片/切片添加元素

切片使用范圍更多 當(dāng)作vector
append添加元素

二維切片[][]string{}

slice := [][]string{}
	slice = append(slice, []string{})
	fmt.Println(len(slice[0]), cap(slice[0]))

5、Range

對于切片或者有序序列

可以Range用法如下 可用_代替range不用的值

package main

import "fmt"

func main() {slice := [][]string{}
	slice = append(slice, []string{})
	for index, str := range slice {fmt.Println(index, str)
	}

	for _, str := range slice {fmt.Println(str)
	}

	for index, _ := range slice {fmt.Println(index)
	}
}

6.1、映射/map的初始化

就像是c++中的map底層是用紅黑樹實現(xiàn)的
初始化map的方式map[key_type]value_type

111.go

package main

import "fmt"

func main() {map_ := map[string]int{}
	var m = make(map[string]int)
	map_["gogo"] = 1
	map_["thanks"] = 2
	m["gogo"] = 1
	m["thanks"] = 2

	fmt.Println(map_["gogo"], map_["thanks"])
	fmt.Println(m["gogo"], m["thanks"])
}

6.2、映射/映射的基本操作

下面的操作包括 插入值 刪除值 查找值

package main

import "fmt"

func main() {map_ := map[string]int{}
	map_["gogo"] = 1
	map_["thanks"] = 2

	elem, ok := map_["gogo"]
	fmt.Println(elem, ok)

	elem, ok = map_["go"]
	fmt.Println(elem, ok)

	map_["gogo"] = 3
	elem, ok = map_["gogo"]
	fmt.Println(elem, ok)

	delete(map_, "gogo")
	elem, ok = map_["gogo"]
	fmt.Println(elem, ok)
}

運(yùn)行效果
在這里插入圖片描述


7.1、函數(shù)/函數(shù)值

函數(shù)可以生成為類似于c++的可執(zhí)行函數(shù)對象 或者可以捆綁的執(zhí)行函數(shù)對象

package main

import "fmt"

func mul(x int, z int) int {return x * z
}

func mulfunc(func_ func(int, int) int, z int) int {return func_(3, 5) * z
}

func main() {funcobj := func(x, y int) int {return x * y
	}

	fmt.Println(funcobj(2, 3))
	fmt.Println(mul(funcobj(2, 3), 20))
	fmt.Println(mulfunc(funcobj, 20))
}

運(yùn)行效果
在這里插入圖片描述


7.2、函數(shù)/函數(shù)閉包

剛剛仔細(xì)去看了一下 發(fā)現(xiàn)并沒有那么好理解

用我的話來解釋一下 閉包內(nèi)部聲明的參數(shù) 其參數(shù)的聲明期是和函數(shù)閉包對象的生命期一樣的
并且返回一個匿名函數(shù) 之后匿名函數(shù)也可以使用之前聲明的函數(shù)對象

下面是簡單的使用例子 后續(xù)復(fù)雜的使用還要再琢磨琢磨
111.go

package main

import "fmt"

func add() func() int {i := 0
	return func() int {i += 1
		return i
	}
}

func deleter(x int) func(x int) int {i := 100
	return func(x int) int {i -= x
		return i
	}
}

func main() {Adder := add()
	fmt.Println(Adder())
	fmt.Println(Adder())

	Deleter := deleter(10)
	fmt.Println(Deleter(20))
	fmt.Println(Deleter(30))	
}

運(yùn)行效果
在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:Go學(xué)習(xí)之路:更多類型:struct、slice和映射(DAY2)-創(chuàng)新互聯(lián)
文章地址:http://weahome.cn/article/psiji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部