Go 其三 Map與String

  藝多不壓身,學習一下最近蠻火的Go語言,整理一下筆記。相關Code和筆記也放到了Git上,傳送門git

MAPgithub

Map 聲明golang

m := map[string]int{"one":1, "two":2, "three":3}
m1 := map[string]int{}
m1["one"] = 1

m2 := make(map[string]int, 10/*Initial Capacity*/)
//爲何不初始化len? 對於切片 s := make([]int, 3, 5) 會指定len並給默認的0值,但語義上Map其實沒辦法指定默認值的,所以沒有len.

 

Map元素的訪問
與其餘主要變成語言的差別
當訪問的Key不存在時,仍會返回零值,不能經過返回nil來判斷元素是否存在,能夠用以下方式判斷數組

if v,ok:=m1[3];ok{
  t.Logf("Key 3's value is %d", v)
} else {
  t.Log("Key 3 is not existing.")
}

其中ok爲bool值,當值存在時,ok的值爲true函數

 

Map遍歷學習

m := map[string]int{"one":1, "two":2, "three":3}
for k,v := range m {
    t.Log(k,v)
}

 

附上測試代碼:測試

package my_map

import "testing"

func TestInitMap(t *testing.T){
	m1:=map[int]int{1:1,2:4,3:9}
	t.Log(m1[2])
	t.Logf("len m1=%d", len(m1))
	m2:=map[int]int{}
	m2[4]=16
	t.Logf("len m2=%d", len(m2))
	m3:=make(map[int]int,10)
	t.Logf("len m3=%d", len(m3))

	//cap()是不能用於求map的capacity的. 下面的code會報錯:invalid argument m3 (type map[int]int) for capgo
	//t.Logf("len m3=%d", cap(m3))
}

func TestAccessNotExistingKey(t *testing.T){
	m1:=map[int]int{}
	t.Log(m1[1])
	m1[2] = 0
	t.Log(m1[2])

	//以上的輸出結果爲
	/*
		TestAccessNotExistingKey: map_test.go:21: 0
		TestAccessNotExistingKey: map_test.go:23: 0
	*/
	//  但實際上m1[1]是不存在的值,m1[2]是存在但值爲0,這是兩種狀況 事實上當value不存在時Go會給賦一個默認值
	//好處是這樣不會有空指針異常,壞處是須要額外判斷一下是不存在仍是自己就是零值。具體判斷方式以下:

	if v,ok:=m1[3];ok{
		t.Logf("Key 3's value is %d", v)
	} else {
		t.Log("Key 3 is not existing.")
	}

	m1[3] = 0

	if v,ok:=m1[3];ok{
		t.Logf("Key 3's value is %d", v)
	} else {
		t.Log("Key 3 is not existing.")
	}
}

func TestTraveMap(t *testing.T){
	m1:=map[int]int{1:1,2:4,3:9}
	for key,value := range m1{
		t.Log(key,value)
	}
}

 

Map與工廠模式
Map的value能夠是一個方法
與Go的Dock type接口方式一塊兒,能夠方便的實現單一方法對象的工廠模式編碼


實現Set
Go的內置集合中沒有Set實現,能夠map[type]boolspa

  1. 元素的惟一性
  2. 基本操做

    添加元素指針

    判斷元素是否存在

    刪除元素

    元素個數

 

附上代碼:

package map_ext

import "testing"

func TestMapWithFunValue(t *testing.T){
	m:=map[int]func(op int)int{}
	m[1] =func(op int) int {return op}
	m[2] =func(op int) int {return op * op}
	m[3] =func(op int) int {return op * op * op}

	t.Log(m[1](2),m[2](2),m[3](2))
}

func TestMapForSet(t *testing.T){
	mySet:=map[int]bool{}

	//1) 添加元素
	mySet[1] = true

	n:=1

	//2) 判斷元素是否存在
	if mySet[n] {
		t.Logf("%d is existing", n)
	} else {
		t.Logf("%d is not existing", n)
	}

	//3) 刪除元素相似
	delete(mySet, 1)

	//4) 元素個數
	t.Log(len(mySet))


	// 刪除元素後顯示 1 is not existing
	if mySet[n] {
		t.Logf("%d is existing", n)
	} else {
		t.Logf("%d is not existing", n)
	}
}

  

字符串

字符串
與其餘主要變成語言的差別

  1. Go中string是數據類型,不是引用或指針類型,因此它的零值是""而不是null
  2. string是隻讀的byte slice, len函數返回的其實是string所包含的byte數,與具體string包含多少字符是不一樣的
  3. string的byte數組能夠存聽任何數據

Unicode 和 UTF8

  1. Unicode 是一種字符集(code point)
  2. UTF8是unicode的存儲實現(轉換爲字節序列的規則)

編碼與存儲

字符 「中」
Unicode 0x4E2D
UTF-8 0XE4B8AD
string/[]byte [0xE4,0xB8,0xAD]


經常使用字符串函數

  1.  strings包 https://golang.org/pkg/strings/
  2.  strconv包 https://golang.org/pkg/strconv/

 

附上代碼:

package string_test

import "testing"

func TestString(t *testing.T){
	var s string
	t.Log(s)
	t.Log(len(s))

	s = "\xE4\xB8\xA4" //即便是不可顯示的字符也能夠存儲,如"\xE4\xBB\xA5"將顯示亂

	t.Log(s)
	t.Log(len(s)) //輸出結果爲3,但其實對應的是一箇中文字符 ‘兩’

	// string是不能夠變的byte slice,所以不能給它賦值
	a := "Hello"
	//a[1] = '3' // 報錯:cannot assign to a[1]go
	t.Log(a)

	b := "中"
	t.Log(len(b)) //是byte數
	c := []rune(b) //rune可以取出字符串中的unicode,這是Go的一個內置機制
	t.Log(len(c))
	t.Logf("中 unicode %x", c[0])
	t.Logf("中 UTF8 %x", s)
	//以上四個log輸出的結果分別爲:
	/*
	    TestString: string_test.go:21: 3
		TestString: string_test.go:23: 1
		TestString: string_test.go:24: 中 unicode 4e2d
		TestString: string_test.go:25: 中 UTF8 e4b8a4
	*/
}

func TestStringToRune(t *testing.T){
	s:= "中華人民共和國"
	for  _,c:=range s{
		t.Logf("%[1]c %[1]d",c)
	}

	/*d
		以上運行結果爲
		    TestStringToRune: string_test.go:38: 中 20013
			TestStringToRune: string_test.go:38: 華 21326
			TestStringToRune: string_test.go:38: 人 20154
			TestStringToRune: string_test.go:38: 民 27665
			TestStringToRune: string_test.go:38: 共 20849
			TestStringToRune: string_test.go:38: 和 21644
			TestStringToRune: string_test.go:38: 國 22269

		注意這裏看代碼可能有些彆扭,這裏的‘%[1]c %[1]d’ 其實意思是 以%c的格式格式化第1個字符 和 以%d的格式格式化第1個字符
	*/
}
相關文章
相關標籤/搜索