自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 語(yǔ)言設(shè)計(jì)失誤,缺乏遠(yuǎn)見?

開發(fā) 后端
為什么 Go 語(yǔ)言這么久都沒(méi)有泛型,是不是 Go 官方不夠 “聰明”,抄作業(yè)都不會(huì)抄。這顯然是不對(duì)的。

[[429956]]

本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚了」,作者陳煎魚 。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚了公眾號(hào)。

大家好,我是煎魚。

前段時(shí)間我有一個(gè)朋友在某站點(diǎn)上摸魚時(shí),給我甩來(lái)一個(gè)主題為《golang 設(shè)計(jì)者是如何償還技術(shù)債的》鏈接。

說(shuō)是讓我學(xué)習(xí)、圍觀一下社區(qū)觀點(diǎn),早日好修成正果,本魚表示滿臉問(wèn)號(hào)。

原回答如下圖:

主要是以極短的話語(yǔ)表述 Go 語(yǔ)言的 “泛型、異常、channel、annotation、模塊依賴” 的設(shè)計(jì)是失誤的。

說(shuō)是沒(méi)有向各種編程語(yǔ)言的 “最佳實(shí)踐” 各取所需。

那些故事

剛好煎魚也入門 Go 沒(méi)幾天,偶爾翻過(guò) issues 和 proposal,看了一點(diǎn)點(diǎn)歷史事件。

圖來(lái)自 Introduction to Golang

也從我的觀點(diǎn)來(lái)圍觀一下 Go 官方這些年為特性掙扎過(guò)的那些事。

涉及:

  • 泛型。
  • 錯(cuò)誤處理。
  • 依賴管理。
  • 注解。

泛型

為什么 Go 語(yǔ)言這么久都沒(méi)有泛型,是不是 Go 官方不夠 “聰明”,抄作業(yè)都不會(huì)抄。這顯然是不對(duì)的。

有如下幾點(diǎn)原因:

  • 泛型本質(zhì)上并不是絕對(duì)的必需品。
  • 泛型不是 Go 語(yǔ)言的早期目標(biāo)。
  • 其他 feature 更重要,把精力放在這些上面,Go 團(tuán)隊(duì)人力很有限的。

歷史嘗試

在以往的嘗試中,Go 團(tuán)隊(duì)有人進(jìn)行過(guò)不少的泛型 proposal 試驗(yàn)?;緯r(shí)間線(via @changkun)如下:

簡(jiǎn)述 時(shí)間 作者
Type Functions 2010年 Ian Lance Taylor
Generalized Types 2011年 Ian Lance Taylor
Generalized Types v2 2013年 Ian Lance Taylor
Type Parameters 2013年 Ian Lance Taylor
go:generate 2014年 Rob Pike
First Class Types 2015年 Bryan C.Mills
Contracts 2018年 Ian Lance Taylor, Robert Griesemer
Contracts 2019年 Ian Lance Taylor, Robert Griesemer
Redundancy in Contracts(2019)'s Design 2019年 Ian Lance Taylor, Robert Griesemer
Constrained Type Parameters(2020, v1) 2020年 Ian Lance Taylor, Robert Griesemer
Constrained Type Parameters(2020, v2) 2020年 Ian Lance Taylor, Robert Griesemer
Constrained Type Parameters(2020, v3) 2020年 Ian Lance Taylor, Robert Griesemer

我們觀察一下,10 年過(guò)去了,Ian Lance Taylor 依然在開展泛型提案,持續(xù)地在思考著 Go 泛型。

堅(jiān)持思考,這一點(diǎn)值得我們學(xué)習(xí)。

下一步計(jì)劃

在 2021 年尾巴的我們,明年(2022年) Go1.18 左右就可以見到 Go 泛型,基本跑不了。

在出來(lái)前可以看看《Go 1.17 支持泛型了?具體怎么用》,可以作為玩具用了。

接下來(lái)可以預(yù)見泛型出來(lái)后,一堆工具庫(kù)和數(shù)據(jù)結(jié)構(gòu)很大可能會(huì)被逐步改寫,像是《Go 提案:增加泛型版 slices 和 maps 新包》,早已摩拳擦掌。

屆時(shí) Go 源碼類別的書的部分內(nèi)容也會(huì)失時(shí)效,需要關(guān)注 Go 版本的時(shí)效性。

錯(cuò)誤處理

在日常工程中,我們寫的、看到最多的可能就是這一段標(biāo)志性 Go 代碼:

  1. func main() { 
  2.  x, err := foo() 
  3.  if err != nil { 
  4.    // handle error 
  5.  } 
  6.  y, err := foo() 
  7.  if err != nil { 
  8.    // handle error 
  9.  } 
  10.  z, err := foo() 
  11.  if err != nil { 
  12.    // handle error 
  13.  } 
  14.  s, err := foo() 
  15.  if err != nil { 
  16.    // handle error 
  17.  } 

這是在業(yè)內(nèi)被吐槽的最多的,甚至都可以用來(lái)作為 Gopher 的互認(rèn)。

設(shè)計(jì)方向

那 Go 是瞎設(shè)計(jì)的嗎,就粗制濫造,搞個(gè)錯(cuò)誤 err 的返回約定慣例。像是:

  1. func foo() err { 
  2.     return nil 

其實(shí)并不是,Go 團(tuán)隊(duì)在設(shè)計(jì)上有意識(shí)地選擇了顯式的設(shè)計(jì)方向,如下:

  • 使用顯式錯(cuò)誤結(jié)果。
  • 使用顯式錯(cuò)誤檢查。

這和其他語(yǔ)言不一樣 ,是由于 Go 團(tuán)隊(duì)也認(rèn)識(shí)到了異常處理的不可見錯(cuò)誤檢查所帶來(lái)的問(wèn)題。

設(shè)計(jì)草案有一部分是受到了這些問(wèn)題的啟發(fā)。如下:

目前 Go 官方也沒(méi)有打算去掉 “顯式” 這一做法,新版 Go2 錯(cuò)誤處理的核心目標(biāo)是:“錯(cuò)誤檢查更加輕便,減少專門用于錯(cuò)誤檢查的 Go 程序代碼的數(shù)量和所花費(fèi)的時(shí)間。”。

從 Go2 的趨勢(shì)來(lái)看,主要是增加關(guān)鍵字和修飾來(lái)解決這個(gè)問(wèn)題,相當(dāng)于是堆積木了,而不是直接把他干掉的。

這在 Go 核心團(tuán)隊(duì)內(nèi)是非常明確的。

依賴管理

Go 語(yǔ)言在一開始是完全基于 GOPATH 作為依賴管理的模式,當(dāng)時(shí)也鬧了不少的爭(zhēng)議出來(lái)。有以下核心問(wèn)題:

依賴要手動(dòng)拉取和下載,沒(méi)有強(qiáng)版本化的概念,開發(fā)者很難受(例如:不兼容升級(jí)、要拉取同一份)。

依賴和工程代碼必須在 GOPATH 下才能運(yùn)行,不能任意擺放。

所以在 Go1.0~Go1.11 中,各路神仙發(fā)招,社區(qū)出現(xiàn)了各種諸如 dep、glide、godep 等依賴包管理工具。

時(shí)間線

后續(xù) Go 團(tuán)隊(duì)在 Russ Cox 的強(qiáng)勢(shì)推進(jìn)下,力排眾議,推動(dòng) Go modules 的發(fā)展:

時(shí)間線如下:

  • Go1.11 起開始推進(jìn) Go modules(前身 vgo)。
  • Go1.13 起不再推薦使用 GOPATH 的使用模式。
  • Go1.14 表示已經(jīng)準(zhǔn)備好,可以用在生產(chǎn)上(ready for production)了。

為什么這么晚

為什么 Go modules 這么晚才誕生,這是不是就是 Go 團(tuán)隊(duì)的設(shè)計(jì)失誤呢?

我認(rèn)為,是也不是。

Go 的誕生一開始是為了解決 Google 幾位大佬自己的痛點(diǎn)。

在 Google 的依賴管理上,本身是大倉(cāng)庫(kù)(Monorepo)的模式,企業(yè)內(nèi)部有自己一整套工具和流程,設(shè)計(jì)之初沒(méi)有這塊的強(qiáng)訴求。

如下:

圖來(lái)自 Mono Repo vs Multi Repo

有興趣的讀者詳細(xì)可閱讀《Why Google Stores Billions of Lines of Code in a Single Repository》,

Go 在社區(qū)開源后,大規(guī)模使用后這個(gè)問(wèn)題就爆發(fā)了,社區(qū)自行釋出了方案??上В寤ò碎T,也都沒(méi)有解決好。官方隊(duì)伍就自己上手了。

要知道,沒(méi)有技術(shù)方案是完美的。Go modules 也被不少人所吐槽,存在爭(zhēng)議。

注解

Go 開發(fā)者中有大部分同學(xué)都有其他語(yǔ)言的使用經(jīng)驗(yàn)。在其他語(yǔ)言中,注解是一個(gè)強(qiáng)大的工具,沒(méi)得用會(huì)很不習(xí)慣。

圖片來(lái)自網(wǎng)絡(luò)

甚至有聽過(guò)沒(méi)有注解,就自嘲不會(huì) “寫” 代碼了,所以一上來(lái)就找 Go 語(yǔ)言的注解怎么用了。

一些疑惑

我有一個(gè)朋友,經(jīng)常會(huì)聽到如下疑惑,甚至無(wú)奈的發(fā)問(wèn):

“怎么樣在函數(shù)前聲明,直接開啟事務(wù)?”

"為什么 Java 可以完美注解,Go 就不行,難以理解,我無(wú)法接受..."

“那 Go 支持什么程度的注解?”

Go 的 “注解” 支撐的非常有限,基本都是 //go build、go:generate 這類輔助,達(dá)不到標(biāo)準(zhǔn)的裝飾器的作用。

為什么不支持

沒(méi)有全面的支持注解來(lái)做裝飾器,顯然不算 Go 的設(shè)計(jì)失誤,這是刻意為之,這是與錯(cuò)誤處理的設(shè)計(jì)理念相關(guān)聯(lián)。

Go issues 上有人提過(guò)類似的提案:

Go Contributor @ianlancetaylor 給出了明確的答復(fù),Go在設(shè)計(jì)上更傾向于明確的、顯式的編程風(fēng)格。

優(yōu)缺點(diǎn)如下:

  • 優(yōu)勢(shì):不知道 Go 能從添加裝飾器中得到什么好處,沒(méi)能在 issues 上明確論證。
  • 缺點(diǎn):是明確的,會(huì)存在意外設(shè)置的情況。

因如下原因,沒(méi)有接受注解:

  • 對(duì)比現(xiàn)有代碼方法,這種裝飾器的新的方法沒(méi)有提供比現(xiàn)有方法更多的優(yōu)勢(shì),大到足矣推翻原有的設(shè)計(jì)思路。
  • 社區(qū)內(nèi)的投票,支持的也很少(基于表情符號(hào)的投票),用戶反饋不多。

可能有小伙伴會(huì)說(shuō)了,有注解做裝飾器了,代碼會(huì)簡(jiǎn)潔不少。

但其實(shí) Go 團(tuán)隊(duì)的態(tài)度很明確:

Go 認(rèn)為可讀性更重要,如果只是額外多寫一點(diǎn)代碼,在權(quán)衡后,還是可以接受的。

償還的過(guò)程

如果是在職場(chǎng)中工作多年的小伙伴,其實(shí)不難發(fā)現(xiàn) Go 的發(fā)展史和業(yè)務(wù)的發(fā)展節(jié)奏是類似的。

在社區(qū)中吐槽的主要是兩塊,如下:

  • 為什么這個(gè)功能不如此設(shè)計(jì)?
  • 這個(gè)功能為什么沒(méi)有支持?

不如此設(shè)計(jì)

為什么 Go 語(yǔ)言不如此設(shè)計(jì)?經(jīng)典的像是 Go 的錯(cuò)誤處理(error),很多小伙伴會(huì)先入為主,以其他語(yǔ)言的最佳實(shí)踐,要教 Go 團(tuán)隊(duì)設(shè)計(jì),要 throw,要 catch!

其實(shí)想一下,我們做一個(gè)業(yè)務(wù),這個(gè)業(yè)務(wù)就是 Go 語(yǔ)言。我們需要先做業(yè)務(wù)建模,確定 Go 的核心思想,才能持續(xù)的迭代和設(shè)計(jì)。

Go 語(yǔ)言的設(shè)計(jì)定義很明顯是:既要簡(jiǎn)單、還要顯式,不能有隱式、要避免復(fù)雜,所以社區(qū)傳遞的是 “less is more” 的設(shè)計(jì)理念。

這么想,很多提案的落地,被拒等,都能了解到 Go 語(yǔ)言的設(shè)計(jì)哲學(xué)和團(tuán)隊(duì)理念。

還沒(méi)有支持

為什么 Go 語(yǔ)言的 XXX 功能沒(méi)有支持?經(jīng)典的像是 Go 的泛型、注解等功能。

還沒(méi)有支持的可能性有三點(diǎn),如下:

  • 還沒(méi)有想清楚。
  • 早就被拒絕了。
  • 優(yōu)先級(jí)不夠高。

實(shí)際上和我們業(yè)務(wù)迭代一樣,Go 團(tuán)隊(duì)的人力資源有限,做事會(huì)有優(yōu)先級(jí)。前文所提到的 Russ Cox 就是現(xiàn)在 Go 團(tuán)隊(duì) Leader,每年也會(huì)開相關(guān)的會(huì)議討論事項(xiàng)。

像是 Go 泛型,顯然沒(méi)有,也不會(huì)影響到 Go 在業(yè)務(wù)初期的短期發(fā)展,國(guó)內(nèi)依然存有一定的占用率。2011 年沒(méi)有想清楚,也就一直持續(xù)思考和嘗試了...

而注解,或是你們想到的。很多在 go issues 其實(shí)早就被拒絕過(guò)多次,自然還沒(méi)有支持,也是因?yàn)樗淮罂赡苤苯映霈F(xiàn)了。

推進(jìn)的模式

Go 在推進(jìn)或償還新技術(shù)改進(jìn)時(shí),現(xiàn)在采取的模式都是一樣的。會(huì)先設(shè)計(jì)一個(gè)編譯時(shí)可以指定的 “變量”。

例如:

  • 泛型的 G 變量。
  • Modules 的 GO111MODULE 變量。

再在 Go 的不斷迭代中,推進(jìn)使用和反饋,再推進(jìn)變量的默認(rèn)開啟,逐漸去除。

可以參考 GO111MODULE 的過(guò)程。

總結(jié)

我們?cè)趯W(xué)習(xí)很多語(yǔ)言、技能時(shí),會(huì)以既有的知識(shí)去認(rèn)知,再對(duì)新的對(duì)象建立新的認(rèn)知樹,很容易會(huì)有先入為主的認(rèn)知行為。

但若沒(méi)有及時(shí)思考,就很容易產(chǎn)生偏見。認(rèn)為 XXX 是 XXX,你 Go 語(yǔ)言就應(yīng)該是 XXX,這樣是有失偏頗的。

就像我們行業(yè)經(jīng)常討論的,網(wǎng)上的 A 同學(xué),35 歲被裁員了。那你我,35 歲就 100% 會(huì)下崗嗎?

相反,Go 語(yǔ)言這 10+ 年來(lái),基于自己的設(shè)計(jì)理念。保持了大致一貫的 less is more 設(shè)計(jì)理念,是值得贊許的。

 

我們要知道軟件設(shè)計(jì),是沒(méi)有銀彈的。Go 語(yǔ)言的設(shè)計(jì)理念,有好有壞,社區(qū)也有不少人對(duì)大道至簡(jiǎn)的理念嗤之以鼻。

 

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚了
相關(guān)推薦

2013-08-02 08:59:41

NASA公有云云計(jì)算

2023-03-21 07:57:37

Go語(yǔ)言設(shè)計(jì)模式

2012-03-27 22:53:40

三星

2018-03-12 22:13:46

GO語(yǔ)言編程軟件

2013-08-02 14:10:24

移動(dòng)App交互設(shè)計(jì)

2024-12-13 16:28:43

2023-03-27 00:20:48

2023-10-13 00:00:00

設(shè)計(jì)模式GO語(yǔ)言

2012-10-08 09:25:59

GoGo語(yǔ)言開發(fā)語(yǔ)言

2022-03-13 23:51:39

Web項(xiàng)目Go

2015-11-25 10:43:03

DGORust

2013-03-22 10:55:06

Go

2022-04-18 09:41:14

Go架構(gòu)設(shè)計(jì)

2022-10-30 23:13:30

contextGo語(yǔ)言

2014-10-31 09:48:36

Go語(yǔ)言

2023-12-30 10:22:57

Go語(yǔ)言函數(shù)開發(fā)

2022-03-25 21:57:49

匯編Go語(yǔ)言

2021-01-23 12:47:19

MySQL數(shù)據(jù)庫(kù)Go語(yǔ)言

2013-05-15 09:27:58

2021-05-30 19:29:12

內(nèi)存Go語(yǔ)言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)