一個網站的用戶管理中,通常用戶都會起一個暱稱,固然用戶A和用戶B的暱稱有可能相同,咱們就使用類型爲map[string]int的集合來表示,其中string表明用戶暱稱、int表示暱稱相同的人數。ide
集合數據內容爲:{"chen":20, "chen長":10, "春風":5, "龍ge":13, "where你are":7}。學習
§問題1. 從這個集合中找出只包含中文的用戶暱稱的計數信息網站
上面集合中只有用戶暱稱爲「春風」的元素知足條件,其它像「龍ge」、「chen長」、「where你are」都不是隻包含中文。像看程序實現:spa
users := map[string]int{"chen": 20, "chen長": 10, "春風": 5, "龍ge": 13, "where你are": 7} var targetCount map[string]int = make(map[string]int) for name, count := range users { matched := true for _, v := range name { if v < '\u4e00' || v > '\u9fbf' { matched = false break } } if matched { targetCount[name] = count } } fmt.Println(targetCount)
解釋一下:orm
第一層for循環遍歷users集合,獲得暱稱(name)和計數(count ):字符串
for name, count := range users{get
// ......string
}it
第二層循環遍歷暱稱name字符串中的每一個字符,並判斷是否有非中文字符:for循環
for _, v := range name{
if v <'\u4e00' || v > '\u9fbf' { // 該範圍下的字符爲非中文字符
}
}
【備註】:
這裏由變量matched充當了標誌,當出現非中文字符時,matched被賦爲false,並使用break停止第二層循環,而後判斷該name是否僅爲中文,如果則添加進入targetCountw集合中。
運行結果爲:map[春風:5]
§問題2. 從這個集合中找出只包含中文的用戶暱稱的計數信息,但發現第一個非全中文的用戶暱稱的時候就中止查找。
這裏涉及到map類型的特性問題,當使用for進行遍歷users集合時,順序會出現不肯定性,即第一個暱稱有多是「chen」,也有多是「春風」,也有多是「龍ge」,總之是不肯定的。
假設第一個暱稱是「chen長」時,程序發現它是非全中文的暱稱,這時整個程序須要結束。
for name, count := range users { matched := true for _, v := range name { if v < '\u4e00' || v > '\u9fbf' { matched = false break } } if !matched { break } else { targetCount[name] = count } } fmt.Println(targetCount)
這個程序實現與上面基本是大同小異,不一樣之處在於第一層循環中的matched判斷。
假設在第一層for循環中,第一次取到的暱稱name爲「龍ge」,此時第二層for循環中會逐個字符地查看「龍ge」這個字符串,當程序發現「龍ge」是非全中文時,matched標誌被置爲false,同時跑出第二層循環,而後在第一層循環中問:「取到的暱稱‘龍ge’是否爲全中文?」,結果不是,因而按照題目要求就break掉程序並時跳出第一層循環。
這裏若是您多運行一下程序,就會發現結果有多是不一樣的,有時爲map[],有時爲map[春風:5]
§問題3. 不使用輔助標識(如上例中的matched)解決§問題2.
做者這裏是讓您學習break Label這個東東,因此這裏直接引用做者原話了:「咱們以前說過,break語句能夠與標記(Label)語句一塊兒配合使用。」
L: for name, count := range users { for _, v := range name { if v < '\u4e00' || v > '\u9fbf' { break L } } targetCount[name] = count }
該程序與§問題2程序功能是相同的,只是把標誌matched移除掉了。
一條標記語句能夠成爲goto語句、break語句和contiune語句的目標。標記語句中的標記只是一個標識符,它能夠被置在任何語句的左邊以做爲這個語句的標籤。標記和被標記的語句之間須要用冒號「:」來分隔,即以下所示:
L:
for name, count := range users{
// .....
}
須要注意的是,標記L也是一個標識符,那麼當它在未被使用的時候一樣也會報告編譯錯誤。那麼怎麼使用呢?一種方法就是讓它成爲break的目標,即上面示例中的break L。
標籤L代碼塊包含了第一層for循環,第一層for循環包含了第二層for循環,因此當break L時,它是停止整個標籤L代碼塊,因此這裏會停止兩層for循環。
對比「§問題2」和「§問題3」的兩個代碼實現,「§問題3」的代碼更簡潔一些。
§問題4. 仍是解決問題1的事情,只不過要求使用continue語句,即從這個集合中找出只包含中文的用戶暱稱的計數信息
因爲這裏沒有更多的知識點,因此引用原文:
實際上,Go語言中的continue語句只能在for語句中使用。continue語句會使直接包含它的那個for循環直接進入下一次迭代,換言之,本次迭代不會執行該continue語句後面那些語句(它們被跳過了)。
for name, count := range users { matched := true for _, v := range name { if v < '\u4e00' || v > '\u9fbf' { matched = false break } } if !matched { continue } targetCount[name] = count }
或者
L: for name,count := range users{ for _, v := range name{ if r < '\u4e00' || r > '\u9fbf'{ continue L } } targetCount[name] = count }
OK,在讀這個章節時,只是感受這個例子有點意思,因此分享給你們 :)