成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go:我有注解,Java:不,你沒有!

開發(fā) 后端
作為一位 Go 程序員,你會發(fā)現(xiàn)身邊的同事大多都擁有其他語言的編寫經(jīng)驗(yàn)。那勢必就會遇到一點(diǎn),要把新學(xué)到的知識和以前的知識建立連接。

[[429036]]

大家好,我是煎魚。

作為一位 Go 程序員,你會發(fā)現(xiàn)身邊的同事大多都擁有其他語言的編寫經(jīng)驗(yàn)。那勢必就會遇到一點(diǎn),要把新學(xué)到的知識和以前的知識建立連接。

[[429037]]

圖來自網(wǎng)絡(luò)

特殊在于,Go 有些特性是其他語言有,他沒有的。最經(jīng)典的就是 N 位 Java 同學(xué)尋找 Go 語言的注解在哪里,總要解釋。

為此,今天煎魚就帶大家了解一下 Go 語言的注解的使用和情況。

什么是注解

了解歷史

注解(Annotation)最早出現(xiàn)自何處,翻了一圈并沒有找到。但可以明確,在注解的使用中,Java 注解最為經(jīng)典,為了便于理解,因此我們基于 Java 做初步的注解理解。

在 2002 年,JSR-175 提出了 《A Metadata Facility for the Java Programming Language》,也就是為 Java 編程語言提供元數(shù)據(jù)工具。

這就是現(xiàn)在使用最廣泛地注解(Annotation)的來源。示例如下:

  1. // @annotation1 
  2. // @annotation2 
  3. func Hello() string { 
  4.         return "" 

在格式上均以 “@” 作為注解標(biāo)識來使用。

注解例子

摘抄自 @wikipedia 的一個(gè)注解例子:

  1. //等同于 @Edible(value = true
  2. @Edible(true
  3. Item item = new Carrot(); 
  4.  
  5. public @interface Edible { 
  6.   boolean value() default false
  7.  
  8. @Author(first = "Oompah"last = "Loompah"
  9. Book book = new Book(); 
  10.  
  11. public @interface Author { 
  12.   String first(); 
  13.   String last(); 
  14.  
  15. // 該標(biāo)注可以在運(yùn)行時(shí)通過反射訪問。 
  16. @Retention(RetentionPolicy.RUNTIME)  
  17. // 該標(biāo)注只用于類內(nèi)方法。 
  18. @Target({ElementType.METHOD}) 
  19. public @interface Tweezable { 

在上述例子中,通過注解去做了一系列的定義、聲明、賦值等。若是對語言既有注解不熟,或是做的比較復(fù)雜的注解,就會有一定的理解成本。

在業(yè)內(nèi)也常常會說,注解就是 “在源碼上進(jìn)行編碼”,注解的存在,有著明確的優(yōu)缺點(diǎn)。你覺得呢?

注解的作用

在注解的的作用上,分為如下幾點(diǎn):

為編譯器提供信息:注釋可以被編譯器用來檢測錯(cuò)誤或支持警告。

編譯時(shí)和部署時(shí)處理:軟件工具可以處理注釋信息以生成代碼、XML文件等。

運(yùn)行時(shí)處理:有些注解可以在運(yùn)行時(shí)檢查,并用于其他用途。

Go 注解在哪里

現(xiàn)狀

Go 語言本身并沒有原生支持強(qiáng)大的注解,僅限于以下兩種:

  • 編譯時(shí)生成:go:generate
  • 編譯時(shí)約束:go:build

但這先按不足以作為一個(gè)函數(shù)注解來使用,也無法形成像 Python 那樣的裝飾器行為。

為什么不支持

Go issues 上有人提過類似的提案:

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

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

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

因如下原因,沒有接受注解:

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

可能有小伙伴會說了,有注解做裝飾器了,代碼會簡潔不少。

對此 Go 團(tuán)隊(duì)的態(tài)度很明確:

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

用 Go 實(shí)現(xiàn)注解

雖然 Go 語言官方?jīng)]有原生的完整支持,但開源社區(qū)中也有小伙伴已經(jīng)放出了大招,借助各項(xiàng)周邊工具和庫來實(shí)現(xiàn)特定的函數(shù)注解功能。

GitHub 項(xiàng)目分別如下:

  • MarcGrol/golangAnnotations
  • u2takey/go-annotation

使用示例如下:

  1. package tourdefrance 
  2.  
  3. //go:generate golangAnnotations -input-dir . 
  4.  
  5. // @RestService( path = "/api/tour" ) 
  6. type TourService struct{} 
  7.  
  8. type EtappeResult struct{ ... } 
  9.  
  10. // @RestOperation( method = "PUT", path = "/{year}/etappe/{etappeUid}" ) 
  11. func (ts *TourService) addEtappeResults(c context.Context, year int, etappeUid string, results EtappeResult) error { 
  12.  return nil 

對 Go 注解的使用感興趣的小伙伴可以自行查閱使用手冊。

我們更多的關(guān)心,Go 原生都沒支持,那么開源庫都是如何實(shí)現(xiàn)的呢?在此我們借助 MarcGrol/golangAnnotations 項(xiàng)目所提供的思路來講解。

分為三個(gè)步驟:

  • 解析代碼。
  • 模板處理。
  • 生成代碼。

解析 AST

首先,我們需要用用 go/ast 標(biāo)準(zhǔn)庫獲取代碼所生成的 AST Tree 中需要的內(nèi)容和結(jié)構(gòu)。

示例代碼如下:

  1. parsedSources := ParsedSources{ 
  2.     PackageName: "tourdefrance"
  3.     Structs:     []model.Struct{ 
  4.         { 
  5.             DocLines:   []string{"// @RestService( path = "/api/tour" )"}, 
  6.             Name:       "TourService"
  7.             Operations: []model.Operation{ 
  8.                 { 
  9.                    DocLines:   []string{"// @RestOperation( method = "PUT", path = "/{year}/etappe/{etappeUid}"}, 
  10.                    ... 
  11.                 }, 
  12.             }, 
  13.         }, 
  14.     }, 

我們可以看到,在 AST Tree 中能夠獲取到在示例代碼中所定義的注解內(nèi)容,我們就可以依據(jù)此去做很多奇奇怪怪的事情了。

模板生成

緊接著,在知道了注解的輸入是什么后,我們只需要根據(jù)實(shí)際情況,編寫對應(yīng)的模板生成器 code-generator 就可以了。

我們會基于 text/template 標(biāo)準(zhǔn)庫來實(shí)現(xiàn),比較經(jīng)典的像是 kubernetes/code-generator 是一個(gè)可以參考的實(shí)現(xiàn)。

代碼實(shí)現(xiàn)完畢后,將其編譯成 go plugin,便于我們在下一步調(diào)用就可以了。

代碼生成

最后,萬事俱備只欠東風(fēng)。差的就是告訴工具,哪些 Go 文件中包含注解,需要我們?nèi)ド傻摹?/p>

這時(shí)候我們可以使用 //go:generate 在 Go 文件聲明。就像前面的項(xiàng)目中所說的:

  1. //go:generate golangAnnotations -input-dir . 

聲明該 Go 文件需要生成,并調(diào)用前面編寫好的 golangAnnotations 二進(jìn)制文件,就可以實(shí)現(xiàn)基本的 Go 注解生成了。

總結(jié)

今天在這篇文章中,我們介紹了注解(Annotation)的歷史背景。同時(shí)我們針對 Go 語言目前原生的注解支持情況進(jìn)行了說明。

也面向?yàn)槭裁?Go 沒有像 Java 那樣支持強(qiáng)大的注解進(jìn)行了基于 Go 官方團(tuán)隊(duì)的原因解釋。如果希望在 Go 實(shí)現(xiàn)注解的,也提供了相應(yīng)的開源技術(shù)方案。

你覺得 Go 語言是否需要像和 Java 一樣的注解支持呢?

 

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

2020-12-24 18:46:11

Java序列化編程語言

2020-04-01 17:50:02

Python編程語言

2022-05-11 09:04:50

Go函數(shù)數(shù)組

2009-07-27 14:11:22

硅谷動力

2016-12-28 14:51:46

大數(shù)據(jù)應(yīng)用

2021-09-08 18:35:31

系統(tǒng)調(diào)試日志

2021-06-09 11:28:04

用戶畫像標(biāo)簽

2022-12-28 11:44:19

用戶畫像互聯(lián)網(wǎng)用戶信息

2023-11-01 11:34:40

用戶畫像企業(yè)

2023-06-30 08:26:24

Java注解Java程序元素

2020-05-25 10:05:26

Python 開發(fā)程序員

2022-03-15 07:58:31

SQL風(fēng)險(xiǎn)字符串

2021-07-04 14:19:03

RabbitMQ消息轉(zhuǎn)換

2024-10-17 09:45:03

2020-04-20 13:43:59

黑客聯(lián)網(wǎng)攻擊

2024-01-18 09:38:00

Java注解JDK5

2022-11-11 08:31:39

Java注解注解類

2022-08-08 20:33:12

VolatileJVM

2024-11-14 11:39:10

Order注解接口

2015-07-03 09:37:21

程序員外包公司
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 精品一区二区三区91 | 四虎最新视频 | 99免费视频 | 日韩一区二区三区视频 | 中文字幕视频三区 | 免费国产视频在线观看 | 久久久成人动漫 | 亚洲精品一区中文字幕 | 人人操日日干 | 91久久久久| 午夜欧美日韩 | 人人鲁人人莫人人爱精品 | 亚洲综合在线一区二区 | 久久av在线播放 | 国产乱码一区 | 日本不卡免费新一二三区 | 午夜私人影院在线观看 | 日韩精品一区二区三区视频播放 | 国产亚洲欧美在线 | 国产美女特级嫩嫩嫩bbb片 | 国产精品高潮呻吟久久av野狼 | www国产成人免费观看视频,深夜成人网 | 国产精品久久久久久久久免费 | 99久久婷婷国产精品综合 | 精品一区二区三区在线观看 | 一级全黄少妇性色生活免费看 | 精品成人av | 日韩三级在线观看 | aaaaaaa片毛片免费观看 | 欧美一级三级 | 精品国产一级 | 亚洲精品在线免费播放 | 亚洲欧美一区二区三区1000 | 殴美成人在线视频 | 黄色免费看 | 亚洲国产精品一区 | 国产精品久久久久久久久图文区 | 有码在线| 一区二区在线 | 91亚洲精品国偷拍自产在线观看 | 老牛影视av一区二区在线观看 |