1. 程式人生 > >go語言學習筆記(4)--容器與字符串的基本概念

go語言學習筆記(4)--容器與字符串的基本概念

都是 empty 知識 nil 來講 java nbsp unicode ...

一、 Slice(切片)

package main

import (
"fmt"
)

//切片,slice
func main() {
arr := [...]int{1,2,3,4,5,6,7,8}
s := arr[2:6] //下標2到下哦5取出來給s
fmt.Print("arr 2 .. 6",s)
fmt.Print("arr :" ,arr[:]) // 這個arr[:]是個視圖。修改的話回改變到,slice本身沒有數據,改變回影響底層

fmt.Println("arr :2", arr[:2])
fmt.Println("arr 2:", arr[2:])
s2 := s[3:5] // 3456

fmt.Println(s2) //雖然沒有,但是還是有值,切片只是改變出事下標的位置,然後數那麽多個就行。

//這裏講有一個重點:slice切片
/***slice結構如下,用c語言的結構體表示
struct slice{
ptr //只想初始位置
len //slice的長度,如果訪問下標超過長度就會報錯
cap //這個是從起始下標一直數到結尾,
}
如上栗子, arr{1,2,3,4,5,6,7}
a[2:6]
那麽這個slice 的ptr是2,len是6-2,cap就是arr.lenth() - ptr所有元素,
在操作的時候,如s2 = s[3:5] 這裏的值只要不超過cap,就不會越界
**slice可以向後擴展,但是不能向前擴展。
*/
//對上面
//可以通過len(s1) ,cap(s1)查看相應的值,還有需要說明的對於數組可以使用%v來作為值得格式控制
fmt.Printf("%v,%d,%d",s,len(s),cap(s))

//slice添加元素
s3 := append(s, 10)
s4 := append(s3, 55) //append,如果slice在原數組得範圍內,對原數組進行修改,、
// 如果超過了就把原來得數組拷過去形成新得數組
fmt.Println(s3,s4)
//多說一句,這裏得數組拷過去,原來得數組就會被垃圾回收機制回收掉。沒錯,go語言具有垃圾回收機制
//append可能造成slice內部得3個值都改變,所以對這個append需要使用一個slice來接收如上,s3與s4都是slice

//跳到函數講解,
opslice()
}

func opslice(){
//創建slice,數組方式就先不說了
//1
var s []int // zero value for slice is nil .這個時候slice s 就是一個空 nil
s = append(s, 1)//增加一個元素1
fmt.Println(s)

s1 := []int{1,2,3,4,5} //這是一個slice
fmt.Println(s1)

s2 := make([]int,16) //創建一個長度為16的slice,知道長度,不知道值 //全是0

s3 := make([]int,2,5) //類型,長度,cap ,這裏的3個參數 //全是0
fmt.Println(s1,s2,s3)

//slice的復制
s3[0] = 1
copy(s2,s3)//把s3 復制給 s2
fmt.Println(s2,s3) //復制只是按位復制,不是把整個樣子復制過去

//slice刪除 我要刪掉第3個元素
s1 = append(s1[:3],s1[4:]...)//第二的參數4開頭所有元素表示法
fmt.Println(s1)

//拿到頭尾就不講了,。。。取值再刪除
}

二、 Map

package main

import "fmt"

//map
func main() {
//map的定義
//1
m := map[string]string{
"a":"a",
"b":"b" ,
"c":"c",//鍵與值的對應關系,註意最後的這個逗號
}
s := m["a"] //取得相應的值
fmt.Println(s)

//2
m2 := make(map[string]string) //定義一個空的map
var m3 map[string]string //空的map
fmt.Println(m2,m3) //這樣的話,m2 = empty map ;m3 = nil

//map的遍歷
for k,v := range m {
//k := range m // 這樣只拿k
//_,v := range m //這樣就只拿值 很少有只拿值得情況
/**
聯想,前面還想也有類似得用法,是在range第二次出現的時候,數組下標與數組值得取得
*/
fmt.Println(k,v) //這個map是一個hashmap
}

//取值小demo
s1 := m["a"]
s2 := m["sdfasdf"] //明顯不存在

//當然還能這樣
s3,is := m["adfaf"]
fmt.Println(s1,s2) //此時輸出的s2 ,,官方說法,這是一個zero value
fmt.Println(s3,is) //如果是一個不存在的鍵,會是zero value,is值也會是false
/***
知識點,什麽是zero value -->字面意思 就是0 或者空串等,理解下
*/

//那麽講下用法
if s4,ok := m["b"];ok{
fmt.Println(s4) //這樣的情況
}else {
fmt.Println("沒有這個鍵")
}

//map 刪除元素
delete(m,"c") // 直接刪除,

/***
知識點,什麽類型可以作為key呢?
‘‘‘‘java中要作為key,必須實現hashcode和equals,
go語言中,
首先要能夠判斷是否相等,
其次除了slice,map,function的內建類型都可以作為key
還有就是結構體,不包含上面這幾個字段,也可以作為key,編譯的時候就會檢查
*/
}

三、 字符串講解。

package main

import (
"fmt"
"unicode/utf8"
)

//字符串講解
func main() {
var s string = "yes,我愛go語言!"
fmt.Println(len(s)) //結果是21,一個英文一個字節,一個中文3個字節,采用utf-8的編碼,這是一種可變長度的編碼方方式

for i,ch := range []byte(s) {
fmt.Printf("(%d,%X)",i,ch)//這樣是解碼之後的,就是才用utf-8的,%X表示以16位輸出
}
fmt.Println()
for i,ch := range s {
fmt.Printf("(%d,%X)",i,ch)//這樣是解碼之後的,是unicode,不可變,
}
fmt.Println()
for i,ch := range []rune(s) {
fmt.Printf("(%d,%X)",i,ch)//這樣是解碼之後的,同意為rune類型,支持國際化,全是int32
}
fmt.Println()

//接下來講幾個方法
utf8.RuneCountInString(s) //計算長度,通過utf-8計算的

ch,size := utf8.DecodeRune([]byte(s)[7:]) //通過utf-8解碼 //這裏可以返回兩個值,一個是解碼的每一個字符,一個是這個字符站的字節數
//這是將一個字節數組拿去解碼,按照utf-8解碼,出錯同意返回
?,1
fmt.Printf("%c,%d",ch,size)


}

go語言學習筆記(4)--容器與字符串的基本概念