Go語言學習筆記02--go語言運算子與流程控制分支語句
1.併發概念概述 併發指的是同一時間的多次訪問。解決併發途徑一般就是建立多個伺服器去分流訪問, 對於伺服器而言,響應速度越快那麼併發量肯定就越高。 或者是通過語言邏輯來解決分流。go語言對於併發天生支援性就非常好 ps:開啟mac系統終端快捷方式 cmd+space ps:檢視go安裝版本 go version 2.字元和字串的區別 1)轉義字元 go語言中使用\反斜線表示轉義字元,\反斜線配合其他的字元進行組合能夠在字串中擁有特殊的含義 例如: \n 換行 \r 回車 \\ 輸出單一反斜線 \" 雙引號 \0 字串結束符號 ps:在很多語言中\'轉義字元都用來表示單引號,但是在go語言中卻並不存在這樣的轉義字元。 其原因是因為在go語言中''單引號是用來表示字元的,並不能用於建立字串。 字串僅能夠通過""雙引號來定義,因此在雙引號之內使用單引號的做法不會報錯。 ps:\0轉義字元是一個非常特殊的轉義字元,本轉義字元表示的是一個“邊界”的含義。 本字元一般不能夠在字串內部顯式寫出表示,而是僅僅在程式執行的時候在記憶體中進行生效。 如果在字串中顯示寫出,也表示的是八進位制數而不是\0結束位(077 014這樣的值) 例如%s等佔位符進行格式化輸入輸出的時候就會通過檢測\0來實現。 2)字串操作方法,獲取長度len() var str1 string = 'hello'; var str2 string = '你好'; num1:=len(str1);//5; num2:=len(str2);//6 ps:go語言中每一箇中文字元佔有3個字元位數,這是為了與linux系統進行對應統一。 3.佔位符的使用 1)特殊佔位符 %T 列印變數對應的資料型別 var num1 float64 = 10; fmt.Printf("%T", num1);//float64 %% 直接列印%百分號本身 fmt.Printf("35%%");//35% 2)進位制與進位制轉換 八進位制:go語言中八進位制的資料採用0開頭,後面的內容中不允許有超過7的數字 num:=0123; //相當於十進位制中64*1+8*2+1*3 十進位制:go語言中的資料主要採用十進位制。 num:=123; 十六進位制:go語言中十六進位制的資料採用0x開頭,後面的內容由abcdef加數字組成 num:=0x123 //相當於十進位制中256*1+16*2+1*3 ps:在go語言中不能夠直接表示二進位制資料,但是可以通過%b進行二進位制格式化輸出。 fmt.Printf("%b",num); ps:在go語言中可以通過%o進行八進位制格式化輸出 fmt.Printf("%o",num); ps:在go語言中可以通過%x或%X來進行十六進位制的格式化輸出,其區別在於輸出顯示是小寫還是大寫 fmt.Printf("%x",num);//0x12ab fmt.Printf("%X",num);//0x12AB ps:%q用於切片,暫且擱置,後續補充... 4.常量 在go語言中使用關鍵字const來定義常量,常量的命名規範等同於變數。 但區別在於常量在定義完成後,其值不能發生改變。 eg: const num int = 10; num = 100; fmt.Println(num);//cannot assign to num(即常量不能修改!) ps:常量和變數雖然都是存放於記憶體之中,但是儲存的位置卻截然不同。 常量儲存於資料區,但是變數可能缺儲存於棧區。 ps:常量不允許直接輸出記憶體地址,只能訪問其值,即參與計算 ps:棧區是系統為每一個應用程式分配的1M的空間來儲存變數,在程式執行結束以後系統會將其自動釋放。 ps:資料區可以再細分為【初始化資料區】【未初始化資料區】【常量區】 ps:常量一般在程式中採用大寫來表示。用於和變數做出區分 ps:字面常量指的是像123 "abc"等這樣直接表示的資料,字面常量也存放於資料區的常量區之內 字面常量其實算是一種硬常量,即不需要計算機進行解析,就能夠直接進行使用的常量。 5.iota列舉 iota是go語言中常量宣告的一個列舉器,其用於生成一組以相似規則初始化的常量, 但是並不用每行都寫一遍初始化的表示式。iota以整數值為常量賦值 eg: const( num1 = 10; num2 = iota; num3 = 100 num4 = iota; num5 = 36; num6 ) fmt.Println(num1,num2,num3,num4,num5,num6);//10,1,100,3,36,5 ps:在const宣告語句中,iota會預設將第一行宣告處設定為0值。 然後隨著每一條宣告語句逐次加一。這個規則與宣告語句中是否使用了iota並無任何關係 ps:iota可以不在const常量宣告結構的第一條語句中使用,也可以不連續使用 但iota列舉取值卻仍然是從第一條語句設定為0值進行逐次遞增。 ps:iota在定義列舉的時候,若多個常量寫在同一條語句內,則這些常量取相同的常量值 const( num1,num2 = iota; num3 = iota; ) fmt.Println(num1,num2,num3);//0,0,1 6.算術運算子 go語言中的算術運算子也仍然和c語言的規則大同小異。 算術運算子只要包括: + - * / % ++ -- 分別表示加法、減法、乘法、除法、取餘、自增、自減 ps:int整數型別與int整數型別的計算,結果為仍舊為整數。(10 / 4 = 2) ps:%取餘操作必須是對整數進行操作,對浮點數進行取餘操作是宣告無效的。(10 % 2.5 => 無效計算) (1)自增自減運算 ++ -- 非常關鍵性的一點就是go語言中的自增自減運算與傳統c語言中的自增自減運算完全不同。 在go語言中++和--只存在後運算,而不存在前運算規則。 (遮蔽了二一性問題,即同樣運算表示式,不同裝置的不同運算順序導致的結果不同問題。 例如b+++a,有的裝置計算過程是【b+】【++a】,有的裝置計算過程是【b++】【+a】) eg: var num int = 10; num++;//合法 num--;//合法 ++num;//違法 --num;//違法 而另外一個非常匪夷所思的地方就是自增自減僅能夠對變數自身生效,而無法進行“再次賦值”! eg: var num int = 10; num1 := num++;//違法! 7.型別轉換 (1)整數與浮點數的型別轉換 在go語言中,不同資料型別的變數是不能夠參與計算的。例如: eg: num1:=10; num2:=3.14; num3:=num1*num2;//違法 為了能夠不同資料型別的變數都能夠參與計算,提出了資料型別轉換的語法:【型別轉換格式(變數)】 這樣就能夠將變數轉換為想要轉變為的資料格式: eg: num1:=10; num2:=3.14; num3:=float64(num1)*num2;//31.400000000000002(浮點數的精度丟失問題) ps:型別轉換的過程中,將浮點型別資料轉換成整形型別資料的時候,是舍掉小數位,而不是四捨五入掉小數位。 num1 := 10; num2 := 3.99; num3:=num1*int(num2);//30 (2)相同資料型別的型別轉換 在go語言中,相同資料型別的變數有時也不能夠互相參與計算。例如 eg: var num1 float32 = 10; var num2 float64 = 20; num3 =: num1 * num2;//違法 必須也要通過型別轉換成為完全相同的資料型別,才能夠進行計算。同理其它資料型別也是一樣的道理。 (3)轉換規則 1)資料轉換的時候通常會從精度低的向精度高的資料型別進行轉換。 eg:float32=>float64。因為這樣會避免因為儲存空間有限導致的精度丟失問題。 2)若資料轉換完成後的資料型別仍不是相同的資料型別,那麼也不能夠繼續參與計算 eg: var num1 float32 = 10; var num2 int = 4; num3 =: float64(num1) * num2;//仍舊是違法的 3)很多其他語言中的int=>string等這樣的操作在go語言中是不允許的 eg: var str string = "100"; var num int = 10; result := int(str) + num;//違法操作! 8.賦值運算子 go語言中的賦值運算子,與傳統c語言中的賦值運算基本沒什麼區別。 = += -= *= /= %= 9.關係運算符(比較運算子) go語言中的關係運算符,與傳統c語言中的關係運算符基本沒什麼區別。 == != > >= < <= 10.邏輯運算子 go語言中的邏輯運算子,與傳統c語言中的邏輯運算子基本沒什麼區別。 && || ! ps:go語言中的邏輯運算子只能對布林型別變數,或布林型別結果的表示式操作 var num1 int = 10; var num2 int = 20; num3 := (num1 && num2);//違法操作! ps:go語言中的邏輯運算子由於只能操作布林型別相關內容, 並且不能使用true,false以外的值表示布林值 因此在go語言中短路運算是一種根本不存在的操作!! 11.指標運算子 go語言中的指標運算子,與傳統c語言中的邏輯運算子基本沒什麼區別。 & * eg: var str string = "abc"; strPointer = &str; newStr = *strPointer; fmt.Println(strPointer); //0xc0007e030 &為取地址符 fmt.Println(newStr); //"abc" *為取地址的值符(指標) fmt.Println(newStr[0]); //97 指標可直接讀取值,但go中讀的是ASCII編碼 fmt.Println(newStr[0+2]); //99 指標可跳步計算,但go中計算結果仍是ASCII編碼 fmt.Println(&newStr); //0xc00007e040 通過指標賦值,與通過變數賦值一樣,但變數之間地址不同 12.運算子優先順序 go語言中的運算子優先順序,與傳統c語言中的運算子優先順序基本沒什麼區別 因此口訣可以直接拿來照搬即可: 初等單目一二級: 初等運算子【()小括號,.點運算,[]中括號】優先順序最高,單目運算子【! & * ++ --】優先順序次之 乘除加減求位移: 算術運算子 * /高於加減,然後是位移運算子<<左位移運算 >>右位移運算 >>>無符號右位移運算 關係等於不等於: 關係運算符 > >= < <= 高於 == != 按位與來異或或: 位運算子 & ^ | 邏輯與或條件弱: 邏輯運算子中 && 高於 || 賦值逗號一點破: 賦值運算子次低,逗號最低 //判斷年份小案例 var year int = 0; fmt.Println("請輸入需要判斷是否為閏年的年份:"); fmt.Scanf("%d",&year); //輸入後一次判斷 var flag1 bool = (year>=0&&year<=9999); var flag2 bool = ((year%4==0)&&(year%100!=0)); var flag3 bool = (year%400==0); //判斷後最終判斷 var flag4 = flag1 && (flag2 || flag3); //製造輸出 if(flag4){ fmt.Printf("%d是閏年",year); }else{ fmt.Printf("%d不是閏年",year); } 13.流程控制分支語句 (1)if條件語句 if 表示式 { 內容 } 表示當表示式的結果為真的時候,執行大括號內的語句。 而如果表示式的結果為假,那麼則直接跳過大括號的內容繼續向後執行。 eg: if num>10 { fmt.Println(num); } 注意:if後的表示式必須為布林值,或計算結果為布林值的表示式 任何int,float,string等型別的資料或表示式結果均必須不能作為判斷依據! 即if num {...}這種寫法完全錯誤! 瞭解:if後的表示式不能寫小括號,這和c語言有著本質的區別 雖然寫小括號也不算錯,但是出於尊重go語言的語法規則來講,最好不要寫。 即 if num>0 {...} 最好不要寫成 if (num>0){...} 重點:對於if語句而言,else語句是一個不可或缺的二元判斷組成部分。 但是在go語言中,對於else的擺放位置做了強制規定 必須緊跟在if後{}大括號的後半部分,而不能重新另起一行!! eg: //正確語法 if num>0 { ... }else{ ... } //完全錯誤 if num>0 { ... } else{ ... } (2)switch分支語句 switch 表示式{ case 結果1: 語句1; case 結果2: 語句2; ... default: 預設語句; } 表示根據switch後表示式的結果,來選擇大括號中的某一種case與之對應的語句情況執行。 而如果所有case後的結果都不能與switch後的表示式結果相匹配,則直接執行default後的預設語句。 eg: switch num{ case 0: fmt.Println('here is 0'); case 1: fmt.Println('here is 1'); ... default: fmt.Println('here is others'); } 注意:switch後的表示式可以是任意型別的結果,不必必須是一個布林值 但是case後的計算結果必須和表示式的型別一致,否則會提示錯誤。 eg: switch num*2{ case 100: //正確! case "str" //錯誤! } 瞭解:同樣出於對go語法的尊重,case後的語句不採用大括號包裹。 直接書寫即可。 重點:在go語言中switch的判斷表示式最好不使用float浮點數來進行判斷 因為浮點數在計算機中是一個大概的約數。 雖然go語言能夠幫我們將浮點數的大小去處理妥當,但為了避免出現不可預知的問題 我們儘量不使用浮點數進行判斷。 重點:在go語言中switch的每一個case之間不必使用break語句去間隔, 多個case語句自然而然的就只有一個會被執行。 重點:如果需要有多個case對應著同樣的一段程式碼執行,那麼需要多個case順次進行執行 那麼需要fallthrough關鍵字來進行說明。 eg: switch num{ case 1: case 2: 語句2; default: 預設語句; } //次數num為1的時候,只會返回一個空白,而不會順次執行case2的語句2! //這和傳統c語言有著明顯的差別(其實也是好事,解決了掉落值的問題) switch num{ case 1: fallthrough; case 2: 語句2; default: 預設語句; } //而下面的這種添加了fallthrough的寫法,則能夠在滿足條件1的情況下 //繼續順次執行case2中的語句2(完美將掉落差問題變成了可控操作。) --------------------- 作者:Frank·Ming 來源:CSDN 原文:https://blog.csdn.net/u013792921/article/details/84341709 版權宣告:本文為博主原創文章,轉載請附上博文連結!