Go:學習筆記兼吐槽(1)

来源:https://www.cnblogs.com/gl1573/archive/2019/01/14/10261281.html
-Advertisement-
Play Games

都說 Go 的語法簡單,學習之後發現,其中的坑真不少,論語法簡單,只服 Python ...


自動添加分號

在很多其他的編程語言中,每一行代碼的結尾都必須有分號(假設一行中只有一句代碼),Golang 的開發者認為,既然每行都要加,不如編譯器自動來加。當然,你加了分號也不會報錯。

Golang 中,在以下兩種情況下會自動加入分號:

  1. 當輸入被斷開為標記時,如果行末標記為

    • 一個標識符

    • 一個整數、浮點數、虛數、字元或字元串文字

    • 關鍵字 break、continue、fallthrough、return 中的一個

    • 運算符和分隔符 ++、--、)、]、} 中的一個

  2. 如果讓複合語句占用單獨一行,則在 )} 後面的分號可以被省略。

Golang 的這個特性,產生了很多寫法上的強制性規定。

(1)函數的左括弧 { 必須和函數定義寫在同一行

這種寫法在其他語言中是絕對沒有問題的,但是在 Golang 中會報找不到方法體,因為根據上面的規則,編譯器會在 func main() 後面自動加上分號。

(2)一條語句只能寫在一行中

如果你一定要把兩條語句寫在一行中,那麼也是可以的,但是必須要在第一條語句後面手動加上分號。但是強烈不建議這麼做。

(3)用 + 拼接字元串時,如果要換行,+ 必須留在行末
var str string = "hello world " + 
    "hello world"

這是可以的,但如果寫成以下形式就不可以了,會報 invalid operation: + untyped string,因為編譯器會在第一行末尾添加分號。


其他例子還有很多,這裡就不一一例舉了,當你用了一個在其他語言中非常合理的寫法而 Golang 編譯報錯時,首先想想看,如果每一句後面都加個分號,代碼還是你預期中的樣子嗎。

回車和換行

\r 是回車符(return),作用是使游標移動到本行的開始位置;
\n 是換行符(newline),作用是使游標垂直向下移動一格;
所以我們一般用 \r\n 來新起一行。

至於為什麼回車和換行要分開,這是一個歷史遺留問題。而現今在很多語言中,\r\n\r\n 都能起到新起一行的作用。但是在 Golang 中,\r 依然只保留了其原始的回車作用。\n\r\n 都能起到換行的作用。

示例 1:
fmt.Println("hello\nworld!")

運行結果:

hello
world!
示例 2:
fmt.Println("hello\rworld!")

運行結果:

world!

這雖然有點坑,但其實還好,一般人換行符都會用 \r\n\n,很少有人會用 \r 吧。

定義的變數或導入的包如果沒有使用到,代碼編譯不能通過

這是強迫症患者的福音,例如我

變數的定義

(1)一般定義

一般語言中,定義變數時是類型在前,變數名在後:

int i = 10

在 Golang 中,是反過來的:

var i int = 10

包括函數傳參時亦是如此:

func test(str string){
    fmt.Println(str)
}
(2)類型推導

定義時若不聲明類型直接賦值,會根據值自行判定變數類型

var i = 10    // i 就是 int 類型
(3)省略 var
name := "Tom"

註意::=,冒號不可省略,省略後就變成賦值了。並且變數名不能是已經聲明過的,因為這是聲明並賦值。
上面的語句等價於:

var name string
name = "Tom"
(4)一次性聲明多個變數
// 方法一
var n1, n2, n3 int

//方法二
var name, age = "Tom"20

//方法三:類型推導
name, age := "Tom"20
(5)聲明全局變數
//方法一
var name string = "Tom"
var age int = 20

//方法二
var (
    name = "Tom"
    age = 20
)

基本數據類型

(1) 整數

整數的類型有很多,int、int8、int16、int32、int64,還有 uint 系列。這裡要說明一下的是 int 這個類型,它在 32 位系統中占 4 個位元組,64 位系統中占 8 個位元組。定義變數時,整數的預設推導類型就是 int 型。

這裡有個吐槽點,我在下麵的隱式轉換中再來吐槽。

(2) 浮點數

沒有 floatdouble,而是用 float32float64 表示。
浮點類型預設聲明為 64 位。

var f = 3.14
fmt.Printf("%T", f)
// 輸出 float64

也可以用科學計數法來表示( E 和 e 都可以)

var f = 3.14E2
(3) 字元類型(char)

Golang 中沒有專門的字元類型,如果要存儲單個的字元,一般用 byte 來保存。

字元串是一串固定長度的字元連接起來的字元序列。在其他語言中,字元串是由字元組成的,而 Golang 的字元串不同,它是由位元組組成的。(此處有坑,稍後詳解)

var c byte = 'a'
fmt.Println("C =", c)
// 輸出 97

當直接輸出字元的值時,實際輸出的是字元對應的碼值。如果需要輸出字元,則需要用格式化輸出。

fmt.Printf("c = %c", c)

Golang 中,中文也可以是一個字元,這在其他一些語言中是不可以的。但是中文的碼值顯然超出了 byte 的範圍,可以用 intrune 來定義。Golang 中統一使用 UTF-8 編碼。

var c rune = '中'
fmt.Printf("%v %c", c, c)
(4) 字元串

多行字元串,用 ` (ESC下麵那個鍵)引起來

var str string = `hello
world`

字元串的預設值是 ""

隱式轉換

Golang 沒有隱式轉換,所有不同類型變數之間必須顯示轉換。類型轉換的基本語法類似 python。

var i int = 100
var f float32 = float32(i)

將一個大的數據類型轉換為一個小的數據類型時(例如 int64 轉 int32),可能導致溢出,溢出不會報錯。

var num1 int64 = 999999
var num2 int8 = int8(num1)  // 轉換結果是63

吐槽開始,也許你覺得,隱式轉換沒有就沒有吧,最多用的時候強轉一下。看下麵的代碼,你還會覺得如此嗎?



不同類型無法比較。想說 fuck 嗎?
之前說道 int 類型的時候,有個要吐槽的,來看下麵的代碼!


不管你是啥系統,int 和 int32、int64 都是不同的類型,想直接比較?沒門!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • (三)功能開發 接上文,我們現在開始編寫Javascript代碼,前文我們主文件已經引入了js文件,只需在js文件中編寫代碼。 1.播放音頻; 怎樣才能讓頁面播放音頻呢?這需要“audio”標簽,但是我們不是在頁面總插入改標簽,而是用JS實現,只需編寫如下代碼: 這裡面要在項目根目錄中添加mp3目錄 ...
  •    系統數據量達到一定程度後必將採用分庫分表的方式來提高系統性能,但傳統的分庫分表方式也必將帶來更高的開發複雜程度。新一代的NewSql及NoSql資料庫由於天生的分散式存儲基因,既保證了能夠橫向擴展,又可以避免較高的開發複雜程度。AppBoxFuture框 ...
  • 第一個問題:什麼是作用域? 第二個問題:作用域在上面情況下形成? 第三個問題:什麼是變數提升,作用域鏈? 第四個問題:“=”賦值運算 第五個問題:生成對象的有幾種方式? 第六個問題:面向對象的三大特點 第七個問題:原型鏈 第八個問題:prototype和__proto__的區別? 第九個問題:jso ...
  • 責任鏈模式為請求創建了一個接受者對象的鏈。這種模式給予請求的類型,對請求的發送者和接受者進行解耦。這種類型的設計模式屬於行為模式。在這種模式下,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該對象,那麼它會把相同的請求傳給下一個接收者,以此類推 ...
  • 解釋器模式 解釋器模式是類的行為模式。給定一個語言之後,解釋器模式可以定義出其文法的一種表示,並同時提供一個解釋器。客戶端可以使用這個解釋器來解釋這個語言中的句子。 意圖 給定一個語言,定義它的文法表示,並定義一個解釋器,這個解釋器使用該標識來解釋語言中的句子。 主要解決 對於一些固定文法構建一個解 ...
  • Java集合類主要由兩個根介面Collection和Map派生出來的,Collection派生出了三個子介面:List、Set、Queue(Java5新增的隊列),因此Java集合大致也可分成List、Set、Queue、Map四種介面體系,(註意:Map不是Collection的子介面)。 ...
  • [TOC] 簡介 服務之間的同步調用,可以使用 HTTP 或 RPC 來完成,但並非所有的調用都需要同步,有些場景下,當客戶端調用服務端時,並不需要等待服務端做出響應,此時就應該使用非同步調用。非同步調用的常用方式是基於 MQ (Message Queue) 來實現的。下文會以 ActiveMQ 為例進 ...
  • 1 import smtplib 2 from email.mime.text import MIMEText 3 from email.mime.multipart import MIMEMultipart 4 """多用戶及帶附件發送郵件代碼""" 5 6 smtpserver = 'smtp.... ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...