Go語言快速入門教程(JAVA轉go)——1 概述

優勢

第一個理由:對初學者足夠友善,能夠快速上手。

業界都公認:Go 是一種非常簡單的語言。Go 的設計者們在發布 Go 1.0 版本和兼容性規范后,似乎就把主要精力放在精心打磨 Go 的實現、改進語言周邊工具鏈,還有提升 Go 開發者體驗上了。演化了十多年,Go 新增的語言特性也同樣是“屈指可數”。

第二個理由:生產力與性能的最佳結合。

Go 創建的最初目的,就是構建流行的、高性能的服務器端編程語言,用以替代當時在這個領域使用較多的 Java 和 C++。而且,Go 也實現了它的這個目標。

Go 語言的性能在帶有 GC 和運行時的語言中名列前茅,與不帶 GC 的靜態編程語言(比如 C/C++)之間也沒有數量級的差距。在各大基準測試網站上,在相同的資源消耗水平的前提下,Go 的性能雖然低于 C++,但高出 Java 不少。

如果你熟悉的是動態語言,那也完全不用擔心。Go 的大部分早期采用者,就來自動態語言程序員群體,包括 Python、JavaScript、Ruby 和 PHP 等語言的使用群體。因為和動態語言相比,Go 能夠在保持生產力的同時,大幅度提高性能。雖然 Go 代碼行數要多于 Python,但他們收獲了近 10 倍的性能提升。

現在,Go 已經成為了云基礎架構語言,它在云原生基礎設施、中間件與云服務領域大放異彩。同時,GO 在 DevOps/SRE、區塊鏈、命令行交互程序(CLI)、Web 服務,還有數據處理等方面也有大量擁躉,我們甚至可以看到 Go 在微控制器、機器人、游戲領域也有廣泛應用。

第三個理由:快樂又有“錢景”。

Go 最初的目標,就是重新為開發人員帶來快樂。這個快樂來自哪里呢?相比 C/C++,甚至是 Java 來說,Go 在開發體驗上的確有很大提升。籠統來說,這個提升來自于簡單的語法、得心應手的工具鏈、豐富和健壯的標準庫,還有生產力與性能的完美結合、免除內存管理的心智負擔,對并發設計的原生支持等等。而這些良好的體驗,恰恰是你寫 Go 代碼時的快樂源泉。

有報告表明,在騰訊、字節跳動、Uber 等許多公司,Go 都是極其受歡迎,在字節跳動、Uber 內部甚至已經成長為主力語言。

誕生

Go 語言的創始人有三位,分別是圖靈獎獲得者、C 語法聯合發明人、Unix 之父肯·湯普森(Ken Thompson),Plan 9 操作系統領導者、UTF-8 編碼的最初設計者羅伯·派克(Rob Pike),以及 Java 的 HotSpot 虛擬機和 Chrome 瀏覽器的 JavaScript V8 引擎的設計者之一羅伯特·格瑞史莫(Robert Griesemer)。

之所以有這種想法,是因為當時的谷歌內部主要使用 C++ 語言構建各種系統,但 C++ 的巨大復雜性、編譯構建速度慢以及在編寫服務端程序時對并發支持的不足,讓三位大佬覺得十分不便,他們就想著設計一門新的語言。在他們的初步構想中,這門新語言應該是能夠給程序員帶來快樂、匹配未來硬件發展趨勢并適合用來開發谷歌內部大規模網絡服務程序的。

特性

簡單

在 Go 語言中看不到傳統的面向對象的類、構造函數與繼承,看不到結構化的異常處理,也看不到本屬于函數編程范式的語法元素。

Go 語言自身實現起來并不容易,但這些復雜性被 Go 語言的設計者們“隱藏”了,所以 Go 語法層面上呈現了這樣的狀態:

  • 僅有 25 個關鍵字,主流編程語言最少;
  • 內置垃圾收集器,降低開發人員內存管理的心智負擔;
  • 首字母大小寫決定可見性,無需通過額外關鍵字修飾;
  • 變量初始為類型零值,避免以隨機值作為初值的問題;
  • 內置數組邊界檢查,極大減少越界訪問帶來的安全隱患;
  • 內置并發支持,簡化并發程序設計;
  • 內置接口類型,為組合的設計哲學奠定基礎;
  • 原生提供完善的工具鏈,開箱即用;
  • … …
顯式

在 C 語言中,下面這段代碼可以正常編譯并輸出正確結果:

//C 語言在編譯c = a + b這一行時,會自動將短整型變量 a 和整型變量 b,先轉換為 long 類型然后相加,并將所得結果存儲在 long 類型變量 c 中。
#include <stdio.h>
int main() {short int a = 5;int b = 8;long c = 0;c = a + b;printf("%ld\n", c);
}

那如果換成 Go 來實現這個計算會怎么樣呢?

package main
import "fmt"
func main() {var a int16 = 5var b int = 8var c int64c = a + bfmt.Printf("%d\n", c)
}

如果我們編譯這段程序,將得到類似這樣的編譯器錯誤:“invalid operation: a + b (mismatched types int16 and int)”。我們能看到 Go 與 C 語言的隱式自動類型轉換不同,Go 不允許不同類型的整型變量進行混合計算

因此,如果要使這段代碼通過編譯,我們就需要對變量 a 和 b 進行顯式轉型,就像下面代碼段中這樣:

c = int64(a) + int64(b)
fmt.Printf("%d\n", c)

除此之外,Go 語言采用了顯式的基于值比較的錯誤處理方案,函數 / 方法中的錯誤都會通過 return 語句顯式地返回,并且通常調用者不能忽略對返回的錯誤的處理。

這種有悖于“主流語言潮流”的錯誤處理機制還一度讓開發者詬病,社區也提出了多個新錯誤處理方案,但或多或少都包含隱式的成分,都被 Go 開發團隊一一否決了,這也與顯式的設計哲學不無關系。

組合

Go 推崇的是組合的設計哲學。

在 Go 語言設計層面,Go 設計者為開發者們提供了正交的語法元素,以供后續組合使用,包括:

  • Go 語言無類型層次體系,各類型之間是相互獨立的,沒有子類型的概念;
  • 每個類型都可以有自己的方法集合,類型定義與方法實現是正交獨立的;
  • 實現某個接口時,無需像 Java 那樣采用特定關鍵字修飾;
  • 包之間是相對獨立的,沒有子包的概念

Go 語言其實是為我們呈現了這樣的一幅圖景:一座座沒有關聯的“孤島”,但每個島內又都很精彩。那么現在擺在面前的工作,就是在這些孤島之間以最適當的方式建立關聯,并形成一個整體。而 Go 選擇采用的組合方式,也是最主要的方式

Go 語言為支撐組合的設計提供了類型嵌入(Type Embedding)。通過類型嵌入,我們可以將已經實現的功能嵌入到新類型中,以快速滿足新類型的功能需求,這種方式有些類似經典面向對象語言中的“繼承”機制。但區別其實很大

被嵌入的類型和新類型兩者之間沒有任何關系,甚至相互完全不知道對方的存在,更沒有那種父類、子類的關系,以及向上、向下轉型。

垂直組合

通過新類型實例調用方法時,方法的匹配主要取決于方法名字,而不是類型。這種組合方式,我稱之為垂直組合,即通過類型嵌入,快速讓一個新類型“復用”其他類型已經實現的能力,實現功能的垂直擴展。

// $GOROOT/src/sync/pool.go
type poolLocal struct {private interface{}   shared  []interface{}Mutex               pad     [128]byte  
}
//我們在 poolLocal 這個結構體類型中嵌入了類型 Mutex,這就使得 poolLocal 這個類型具有了互斥同步的能力
// 我們可以通過 poolLocal 類型的變量,直接調用 Mutex 類型的方法 Lock 或 Unlock。

另外,我們在標準庫中還會經常看到類似如下定義接口類型的代碼段:

// $GOROOT/src/io/io.go
type ReadWriter interface {ReaderWriter
}
//這里標準庫通過 嵌入接口類型的方式來實現接口行為的聚合,組成大接口,這種方式在標準庫中尤為常用,并且已經成為了 Go 語言的一種慣用法。
水平組合

垂直組合本質上是一種“能力繼承”,采用嵌入方式定義的新類型繼承了嵌入類型的能力。

Go 還有一種常見的組合方式,叫水平組合。和垂直組合的能力繼承不同,水平組合是一種能力委托(Delegate),我們通常使用接口類型來實現水平組合。

Go 語言中的接口是一個創新設計,它只是方法集合,并且它與實現者之間的關系無需通過顯式關鍵字修飾

水平組合的模式有很多,比如一種常見方法就是,通過接受接口類型參數的普通函數進行組合,如以下代碼段所示:

// $GOROOT/src/io/ioutil/ioutil.go
func ReadAll(r io.Reader)([]byte, error)
// $GOROOT/src/io/io.go
func Copy(dst Writer, src Reader)(written int64, err error)

也就是說,函數 ReadAll 通過 io.Reader 這個接口,將 io.Reader 的實現與 ReadAll 所在的包低耦合地水平組合在一起了,從而達到從任意實現 io.Reader 的數據源讀取所有數據的目的。

并發

CPU 都是靠提高主頻來改進性能的,但是主頻提高導致 CPU 的功耗和發熱量劇增,反過來制約了 CPU 性能的進一步提高。2007 年開始,處理器廠商的競爭焦點從主頻轉向了多核。

在這種大背景下,Go 的設計者在決定去創建一門新語言的時候,果斷將面向多核、原生支持并發作為了新語言的設計原則之一。并且,Go 放棄了傳統的基于操作系統線程的并發模型,而采用了用戶層輕量級線程,Go 將之稱為 goroutine

  1. goroutine占用的資源非常小,Go 運行時默認為每個 goroutine 分配的棧空間僅 2KB。goroutine 調度的切換也不用陷入(trap)操作系統內核層完成,代價很低。因此,一個 Go 程序中可以創建成千上萬個并發的 goroutine。而且,所有的 Go 代碼都在 goroutine 中執行,哪怕是 go 運行時的代碼也不例外。
  2. 同時,Go 還內置了并發設計的原語:channelselect。開發者可以通過語言內置的 channel 傳遞消息或實現同步,并通過 select 實現多路channel的并發控制。

采用并發方案設計的程序在單核處理器上也是可以正常運行的,也許在單核上的處理性能可能不如非并發方案。但隨著處理器核數的增多,并發方案可以自然地提高處理性能。

而且,并發與組合的哲學是一脈相承的,并發是一個更大的組合的概念,它在程序設計的全局層面對程序進行拆解組合,再映射到程序執行層面上:goroutines 各自執行特定的工作,通過 channel+select 將 goroutines 組合連接起來。

面向工程

Go 語言設計的初衷,就是面向解決真實世界中 Google 內部大規模軟件開發存在的各種問題,為這些問題提供答案,這些問題包括:程序構建慢、依賴管理失控、代碼難于理解、跨語言構建難等。

語法是編程語言的用戶接口,它直接影響開發人員對于這門語言的使用體驗。在面向工程設計哲學的驅使下,Go 在語法設計細節上做了精心的打磨。比如:

  • 重新設計編譯單元和目標文件格式,實現 Go 源碼快速構建,讓大工程的構建時間縮短到類似動態語言的交互式解釋的編譯速度
  • 如果源文件導入它不使用的包,則程序將無法編譯。這可以充分保證任何 Go 程序的依賴樹是精確的。這也可以保證在構建程序時不會編譯額外的代碼,從而最大限度地縮短編譯時間;
  • 去除包的循環依賴,循環依賴會在大規模的代碼中引發問題,因為它們要求編譯器同時處理更大的源文件集,這會減慢增量構建;
  • 包路徑是唯一的,而包名不必唯一的。導入路徑必須唯一標識要導入的包,而名稱只是包的使用者如何引用其內容的約定。
  • 故意不支持默認函數參數。因為在規模工程中,很多開發者利用默認函數參數機制,向函數添加過多的參數以彌補函數 API 的設計缺陷,這會導致函數擁有太多的參數,降低清晰度和可讀性;
  • 增加類型別名(type alias),支持大規模代碼庫的重構。

由于誕生年代較晚,而且目標比較明確,Go 在標準庫中提供了各類高質量且性能優良的功能包,其中的net/http、crypto、encoding等包充分迎合了云原生時代的關于 API/RPC Web 服務的構建需求。

而且,開發人員在工程過程中肯定是需要使用工具的,Go 語言就提供了足以讓所有其它主流語言開發人員羨慕的工具鏈,工具鏈涵蓋了編譯構建、代碼格式化、包依賴管理、靜態代碼檢查、測試、文檔生成與查看、性能剖析、語言服務器、運行時程序跟蹤等方方面面。

gofmt

這里值得重點介紹的是 gofmt,它統一了 Go 語言的代碼風格,Go 開發者可以更加專注于領域業務中。

在提供豐富的工具鏈的同時,Go 在標準庫中提供了官方的詞法分析器、語法解析器和類型檢查器相關包,開發者可以基于這些包快速構建并擴展 Go 工具鏈。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922002.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922002.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922002.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Rust多進程】征服CPU的藝術:Rust多進程實戰指南

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

OpenCV 高階實戰:圖像直方圖與掩碼圖像深度解析

目錄 一、圖像直方圖&#xff1a;讀懂圖像的 “像素分布報告” 1. 什么是圖像直方圖&#xff1f; 2. 圖像直方圖的核心作用 &#xff08;1&#xff09;分析亮度分布 &#xff08;2&#xff09;判斷對比度高低 &#xff08;3&#xff09;輔助圖像增強與閾值分割 &#xf…

基于stm32的家庭安全監測系統設計

若該文為原創文章&#xff0c;轉載請注明原文出處。一、引言&#xff08;一&#xff09;研究背景及意義背景&#xff1a;隨著智能家居概念的普及&#xff0c;人們對家庭安全、舒適度和節能提出了更高要求。傳統安防系統功能單一、各系統獨立&#xff0c;缺乏聯動和遠程管理能力…

Oracle體系結構-控制文件(Control Files)

一、 原理 (Principle) 核心定位&#xff1a; 控制文件是一個小型的二進制文件&#xff0c;由 Oracle 實例在啟動和操作過程中持續讀寫。它是數據庫物理結構的權威記錄。數據庫無法啟動或正常操作時&#xff0c;如果無法訪問控制文件&#xff0c;實例將無法識別數據文件和重做日…

路由 下一跳 網關 兩個不同網段的ip如何通過路由器互通

路由 (Routing)核心思想&#xff1a;路徑選擇是什么&#xff1f; 路由是指數據包從源主機傳輸到目標主機的整個過程。這個過程就像寄快遞&#xff1a;你需要決定包裹經過哪些中轉站才能最終到達收件人手里。做什么&#xff1f; 網絡中的設備&#xff08;主要是路由器&#xff0…

HiDDeN論文解讀與代碼實現

論文&#xff1a;HiDDeN: Hiding Data With Deep Networks 作者&#xff1a;Jiren Zhu, Russell Kaplan, Justin Johnson, Li Fei-Fei一、研究背景 在圖像信息隱藏領域&#xff0c;通常有兩類典型的應用場景&#xff1a;隱寫 (Steganography) 目標&#xff1a;實現秘密通信。要…

實驗室服務器配置|實驗室多人共享GPU|通過Docker實現Linux系統多用戶隔離與安全防控

利用實驗室服務器跑實驗的時候&#xff0c;通常就是兩種方案&#xff0c;一個是向日葵遠程桌面進行操作&#xff0c;一個是通過ssh進行連接&#xff0c;用ssh的話&#xff0c;一般服務器都在內網&#xff08;例如校園網&#xff09;&#xff0c;是無法在公網&#xff08;不在校…

2019考研數學(二)真題

一、選擇題 (1) (2) (3) (4) 遺漏點&#xff1a;由通解知特解&#xff0c;特解代入微分方程 (5) ★記住這個題&#xff0c;用的泰勒展開(6) (7) 遺忘點&#xff1a; ★伴隨矩陣的秩與原矩陣秩的關系&#xff1a; (8) 錯誤點&#xff1a;粗心 二、填空題 (9) 易混淆點&#xff…

10 分鐘上手 ECharts:從“能跑”到“生產級”的完整踩坑之旅

10 分鐘上手 ECharts&#xff1a;從“能跑”到“生產級”的完整踩坑筆記 如果你也曾 復制了官方 Demo 卻不知道怎么拆、窗口一拉伸圖表就變形、切換標簽頁后內存暴漲——這篇博客就是為你寫的。 我會用 6 個遞進版本 的源碼&#xff0c;帶你把一張 最簡柱狀圖 逐步進化成 可銷毀…

二級緩存在實際項目中的應用

二級緩存在項目中的應用 目錄 1. 二級緩存簡介2. 應用場景3. 重難點分析4. 結合SpringBoot使用5. 最佳實踐與案例6. 總結 1. 二級緩存簡介 1.1 什么是二級緩存 二級緩存&#xff08;Second-Level Cache&#xff09; 是Hibernate框架中的一個重要特性&#xff0c;它提供了應…

深入淺出CRC校驗:從數學原理到單周期硬件實現 (2)CRC數學多項式基礎

數學的優雅&#xff1a;剖開CRC的多項式除法核心看似復雜的CRC校驗&#xff0c;其核心建立在優雅的數學基礎之上。本文將為您揭開CRC算法的數學面紗&#xff0c;讓您真正理解多項式除法的精妙之處。模2運算&#xff1a;CRC世界的特殊算術 CRC計算建立在一種特殊的代數系統上——…

軟考初級有沒有必要考?

對正在學習相關專業的學生或者是行業新人&#xff0c;這篇文章從軟考初級的含義、適合哪些人考、考試難度等方面解答&#xff0c;幫助你判斷要不要報考。一、軟考初級是什么&#xff1f; 軟考初級是軟考體系里面的基礎級別&#xff0c;主要面向在校大學生或是IT行業新人&#x…

11 Prompt 工程進階:Few-shot 與 Chain-of-Thought

11 Prompt 工程進階&#xff1a;Few-shot 與 Chain-of-Thought 前10節總結 & 后10節展望 在前 10 節&#xff0c;我們已經完成了 AI 產品經理的入門階段&#xff1a; 1–3&#xff1a;理解了大模型的基本概念、Token、Prompt 基礎&#xff1b;4–5&#xff1a;體驗了本地部…

ARM1.(ARM體系結構)

1.基本概念嵌入式:以應用為心&#xff0c;以計算機技術為礎&#xff0c;軟便件可被的專用計算機系統。計算機系統的軟件基本組成: 系統軟件、應用軟件。計算機系統的硬件基本組成&#xff1a;運算器、控制器、存諸器、輸入設備、輸出設備日常生活中遇到的專業術語&#xff1a…

Django全棧班v1.01 Python簡介與特點 20250910

從零開始的Python編程之旅 “人生苦短&#xff0c;我用Python。”這不僅僅是Python程序員的口頭禪&#xff0c;更是對Python強大能力的最好詮釋&#xff01;&#xff01;&#xff01; 為什么全世界有超過1500萬開發者選擇Python&#xff1f; 為什么Python連續多年蟬聯最受歡…

【WebApi】什么情況開啟如何開啟緩存

在 ASP.NET Core WebAPI 中開啟緩存是優化性能、減少服務器負載和提升用戶體驗的非常重要的手段。但并非所有情況都適合開啟緩存。 下面我將從 “什么情況下開啟” 和 “如何開啟” 兩個方面為你詳細解釋。 一、什么情況下應該開啟緩存? 總的來說,緩存適用于 “變化不頻繁但…

Go語言類型斷言全解析

類型斷言的基本概念類型斷言(Type Assertion)是Go語言中用于檢查接口值底層具體類型的機制。它本質上是一種運行時類型檢查的操作&#xff0c;允許程序在運行時判斷接口變量是否持有特定的類型值&#xff0c;并提取該類型的值。這是Go語言類型系統中的一個重要特性&#xff0c;…

大模型在題目生成中的安全研究:攻擊方法與防御機制

大模型在題目生成中的安全研究&#xff1a;攻擊方法與防御機制 文章目錄大模型在題目生成中的安全研究&#xff1a;攻擊方法與防御機制一、引言二、大模型在題目生成中的安全漏洞與攻擊方法2.1 大模型在題目生成中的安全漏洞分析2.1.1 訓練數據相關漏洞2.1.2 模型架構與特性相關…

跟做springboot尚品甄選項目(二)

登錄功能的書寫 后端接口的書寫 &#xff08;1&#xff09;創建配置文件 粘貼這兩個文件&#xff08;E:\project\AllProJect\Shangpin Selection\項目材料素材\資料\資料\03-配置文件&#xff09; 在spzx-manager服務的src/resources目錄下創建application.yml、application-…

前后端接口調試提效:Postman + Mock Server 的工作流

前后端接口調試提效&#xff1a;Postman Mock Server 的工作流 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特性都是…