sync.Map是1.9才推薦的并發(fā)安全的map,除了互斥量以外,還運用了原子操作,所以在這之前,有必要了解下 Go語言——原子操作
成都創(chuàng)新互聯(lián)是一家專業(yè)提供烏恰企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、HTML5建站、小程序制作等業(yè)務(wù)。10年已為烏恰眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進行中。
go1.10\src\sync\map.go
entry分為三種情況:
從read中讀取key,如果key存在就tryStore。
注意這里開始需要加鎖,因為需要操作dirty。
條目在read中,首先取消標記,然后將條目保存到dirty里。(因為標記的數(shù)據(jù)不在dirty里)
最后原子保存value到條目里面,這里注意read和dirty都有條目。
總結(jié)一下Store:
這里可以看到dirty保存了數(shù)據(jù)的修改,除非可以直接原子更新read,繼續(xù)保持read clean。
有了之前的經(jīng)驗,可以猜測下load流程:
與猜測的 區(qū)別 :
由于數(shù)據(jù)保存兩份,所以刪除考慮:
先看第二種情況。加鎖直接刪除dirty數(shù)據(jù)。思考下貌似沒什么問題,本身就是臟數(shù)據(jù)。
第一種和第三種情況唯一的區(qū)別就是條目是否被標記。標記代表刪除,所以直接返回。否則CAS操作置為nil。這里總感覺少點什么,因為條目其實還是存在的,雖然指針nil。
看了一圈貌似沒找到標記的邏輯,因為刪除只是將他變成nil。
之前以為這個邏輯就是簡單的將為標記的條目拷貝給dirty,現(xiàn)在看來大有文章。
p == nil,說明條目已經(jīng)被delete了,CAS將他置為標記刪除。然后這個條目就不會保存在dirty里面。
這里其實就跟miss邏輯串起來了,因為miss達到閾值之后,dirty會全量變成read,也就是說標記刪除在這一步最終刪除。這個還是很巧妙的。
真正的刪除邏輯:
很繞。。。。
本文介紹一些Go語言的基礎(chǔ)語法。
先來看一個簡單的go語言代碼:
go語言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來進一步介紹go的基礎(chǔ)語法。
go語言中格式化輸出可以使用 fmt 和 log 這兩個標準庫,
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問中的fmt包。
log包實現(xiàn)了簡單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來介紹一下go的數(shù)據(jù)類型
下表列出了go語言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲的是一個地址,這個地址存儲最終的值。
常量是在程序編譯時就確定下來的值,程序運行時無法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語言的運算符主要包括算術(shù)運算符、關(guān)系運算符、邏輯運算符、位運算符、賦值運算符以及指針相關(guān)運算符。
算術(shù)運算符:
關(guān)系運算符:
邏輯運算符:
位運算符:
賦值運算符:
指針相關(guān)運算符:
下面介紹一下go語言中的if語句和switch語句。另外還有一種控制語句叫select語句,通常與通道聯(lián)用,這里不做介紹。
if語法格式如下:
if ... else :
else if:
示例代碼:
語法格式:
另外,添加 fallthrough 會強制執(zhí)行后面的 case 語句,不管下一條case語句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過標記退出循環(huán):
--THE END--
正則中有分組這個功能,在golang中也可以使用命名分組。
一次匹配的情況
場景還原如下:
有一行文本,格式為:姓名 年齡 郵箱地址
請將其轉(zhuǎn)換為一個map
代碼實現(xiàn)如下:
str := `Alice 20 alice@gmail.com`
// 使用命名分組,顯得更清晰
re := regexp.MustCompile(`(?Pname[a-zA-Z]+)\s+(?Page\d+)\s+(?Pemail\w+@\w+(?:\.\w+)+)`)
match := re.FindStringSubmatch(str)
groupNames := re.SubexpNames()
fmt.Printf("%v, %v, %d, %d\n", match, groupNames, len(match), len(groupNames))
result := make(map[string]string)
// 轉(zhuǎn)換為map
for i, name := range groupNames {
if i != 0 name != "" { // 第一個分組為空(也就是整個匹配)
result[name] = match[i]
}
}
prettyResult, _ := json.MarshalIndent(result, "", " ")
fmt.Printf("%s\n", prettyResult)
輸出為:
[Alice 20 alice@gmail.com Alice 20 alice@gmail.com], [ name age email], 4, 4
{
"age": "20",
"email": "alice@gmail.com",
"name": "Alice"
}
注意 [ name age email]有4個元素, 第一個為""。
多次匹配的情況
接上面的例子,實現(xiàn)一個更貼近現(xiàn)實的需求:
有一個文件, 內(nèi)容大致如下:
Alice 20 alice@gmail.com
Bob 25 bob@outlook.com
gerrylon 26 gerrylon@github.com
...
更多內(nèi)容
和上面一樣, 不過這次轉(zhuǎn)出來是一個slice of map, 也就是多個map。
代碼如下:
// 文件內(nèi)容直接用字符串表示
usersStr := `
Alice 20 alice@gmail.com
Bob 25 bob@outlook.com
gerrylon 26 gerrylon@github.com
`
userRe := regexp.MustCompile(`(?Pname[a-zA-Z]+)\s+(?Page\d+)\s+(?Pemail\w+@\w+(?:\.\w+)+)`)
// 這里要用FindAllStringSubmatch,找到所有的匹配
users := userRe.FindAllStringSubmatch(usersStr, -1)
groupNames := userRe.SubexpNames()
var result []map[string]string // slice of map
// 循環(huán)所有行
for _, user := range users {
m := make(map[string]string)
// 對每一行生成一個map
for j, name := range groupNames {
if j != 0 name != "" {
m[name] = strings.TrimSpace(user[j])
}
}
result = append(result, m)
}
prettyResult, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(prettyResult))
輸出為:
[
{
"age": "20",
"email": "alice@gmail.com",
"name": "Alice"
},
{
"age": "25",
"email": "bob@outlook.com",
"name": "Bob"
},
{
"age": "26",
"email": "gerrylon@github.com",
"name": "gerrylon"
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
總結(jié)
使用命名分組可以使正則表示的意義更清晰。
轉(zhuǎn)換為map更加符合人類的閱讀習慣,不過比一般的根據(jù)索引取分組值麻煩一些。
————————————————
版權(quán)聲明:本文為CSDN博主「butterfly5211314」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:
Go中數(shù)值類型可細分為整數(shù)、浮點數(shù)、復數(shù)三種,每種都具有不同的大小范圍和正負支持。
整型分為兩大類
Go提供了有符號和無符號的整數(shù)類型,同時提供四種大小不同的整數(shù)類型。
取值范圍
等價類型
特殊整型
int 和 uint 分別對應(yīng)特定CPU平臺的字長(機器字大?。?,大小范圍在 32bit 或 64bit 之間變化,實際開發(fā)中由于編譯器和硬件不同而不同。
進制轉(zhuǎn)換
轉(zhuǎn)換函數(shù)
使用注意
字節(jié)長度
Golang提供了兩種精度的浮點數(shù)分別為 float32 和 float64 ,它們的算術(shù)規(guī)范由IEEE754浮點數(shù)國際標準定義,IEEE754浮點數(shù)標準被現(xiàn)代CPU支持。
float32 類型的浮點數(shù)可提供約6個十進制數(shù)的精度, float64 類型的浮點數(shù)可提供約15個十進制數(shù)的精度。通常會優(yōu)先選擇使用 float64 ,因為 float32 累計計算誤差會比較容易擴散。
計算機中復數(shù)(complex)由兩個浮點數(shù)表示,一個表示實部(real)一個表示虛部(imag)。
Go語言中復數(shù)的值由三部分組成 RE + IMi ,分別是實數(shù)部分 RE 、虛數(shù)部分 IM 、虛數(shù)單位 i , RE 和 IM 均為 float 。
Go語言提供兩種類型的復數(shù),分別是 complex64 即32位實數(shù)和虛數(shù), complex128 即64位實數(shù)和虛數(shù), complex128 為復數(shù)的默認類型。
復數(shù)聲明
z 表示復數(shù)的變量名, complex128 表示復數(shù)類型, complex() 內(nèi)置函數(shù)用于為復數(shù)賦值。 x 和 y 分別表示構(gòu)成該復數(shù)的兩個 float64 類型的值, x 為實部, y 為虛部。
簡寫形式
對于 z 值可通過內(nèi)置函數(shù) real(z) 獲取該復數(shù)的實部,使用 imag(z) 獲取虛部。
當前文章:go語言的re標記,cs go標記
標題來源:http://aaarwkj.com/article0/dssghio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、企業(yè)建站、服務(wù)器托管、外貿(mào)網(wǎng)站建設(shè)、手機網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)