Go 泛型的括號選擇:[ ] or ( )?

2020-12-16 開源中國

Go 語言設計者 Robert Griesemer 和 Ian Lance Taylor 近日在 Golang 官方論壇發帖討論關於泛型及其括號使用的問題。

他們提到很多人表達了對泛型語法的擔憂,特別是在類型參數聲明和函數實例以及泛型的括號選擇方面。

常見的計算機鍵盤提供了四對單字符對稱括號,分別是小括號 ( )、方括號 [ ]、花括號 { } 以及尖括號 < >。基於此,他們解釋了目前泛型草案在示例代碼中使用小括號的原因。首先,Go 使用花括號來劃分代碼塊、複合字面量(composite literals)和一些複合類型,因此幾乎不可能在沒有嚴重語法問題的情況下將花括號用於泛型。至於尖括號,解析器在某些情況下要求 <> 需要 unbounded lookahead。

所以只剩下 ( ) 和 [ ] 可供選擇。然而缺少修飾的方括號會在數組和 slice 的類型聲明中造成歧義,在解析索引表達式時也會引起小程度的歧義。因此在設計之初他們決定使用小括號,因為小括號似乎更符合 Go 語言的風格,而且看起來問題最少。

為了使小括號正常工作,並且為了向後兼容,他們表示不得不在類型參數列表中引入type關鍵字。最後,他們在參數列表、複合字面量和嵌入類型中發現了額外的解析歧義,而這些歧義需要嵌套更多的小括號來解決。不過即便如此,他們還是決定繼續使用小括號,因為當時還有更重要的設計問題需要解決。

現在他們決定重新考慮這個最初的決定。如果僅使用方括號聲明類型參數,那麼聲明數組的方式如下所示:

type A [N]E

不過這就無法與泛型的聲明進行區分:

type A[N] E

但如果能接受額外的type關鍵字,那麼歧義就會消失:

type A[type N] E

此外,使用小括號時產生的歧義似乎不會出現在方括號中。下面是一些使用方括號但不需要額外嵌套小括號的例子:

using () using [] func f((T(int)) func f(T[int]) struct{ (T(int)) } struct{ T[int] } interface{ (T(int)) } interface{ T[int] } [](T(int)){} []T[int]{}

為了更好地理解以及進行測試,他們表示將開始對原型實現進行修改,讓泛型能使用小括號或方括號(注意不能同時混用,只能使用其中一種)。這些修改將首先提交到 dev.go2go 分支,最終會出現在 Go playground 上。

Robert 和 Ian 表示,除了使用方括號,還有另外經過充分研究的符號可以選擇,這些方案能讓他們做出更明智的決定。

更多討論查看 https://groups.google.com/forum/#!topic/golang-nuts/7t-Q2vt60J8

相關焦點

  • Go 泛型的括號選擇:「」or ( )?
    他們提到很多人表達了對泛型語法的擔憂,特別是在類型參數聲明和函數實例以及泛型的括號選擇方面。常見的計算機鍵盤提供了四對單字符對稱括號,分別是小括號 ( )、方括號 [ ]、花括號 { } 以及尖括號 < >。基於此,他們解釋了目前泛型草案在示例代碼中使用小括號的原因。
  • Go 泛型的括號選擇:[ ] or ( )? - OSCHINA - 中文開源技術交流社區
    他們提到很多人表達了對泛型語法的擔憂,特別是在類型參數聲明和函數實例以及泛型的括號選擇方面。常見的計算機鍵盤提供了四對單字符對稱括號,分別是小括號 ( )、方括號 [ ]、花括號 { } 以及尖括號 < >。基於此,他們解釋了目前泛型草案在示例代碼中使用小括號的原因。首先,Go 使用花括號來劃分代碼塊、複合字面量(composite literals)和一些複合類型,因此幾乎不可能在沒有嚴重語法問題的情況下將花括號用於泛型。
  • 看懂複雜的TypeScript泛型運算
    但是,當不得不嘗試提高函數或組件的通用性時,使用泛型成了必須的選擇。當嘗試閱讀一些用TypeScript開發的庫的源碼時,可能會被各種尖括號包裹的複雜泛型運算搞的暈頭轉向。本文的目的在於對泛型中的常見關鍵詞和用法進行介紹,並且嘗試用一定數量的例子來方便理解泛型。閱讀本文之前,希望你已經閱讀過TypeScript官方文檔[1]。
  • 如何實現Go泛型的討論 | Gopher Daily (2020.09.19) ʕ◔ϖ◔ʔ
    •有意想學習容器或Kubernets的童鞋可以了解一下我的慕課網實戰課:k8s實戰 - https://coding.imooc.com/class/284.html1.Go泛型如何實現的討論 - https://groups.google.com/g/golang-dev/c/OcW0ATRS4oM 以及Keith Randall提出的兩個實現方案
  • 泛型:泛型的定義(類、接口、對象)、使用、繼承
    泛型(Generic):就是指參數化類型,上面的List<String>就是參數化類型,因此就是泛型,而String就是該List<String>泛型的類型參數;    3) 泛型的好處:         i.
  • Go 泛型草案更新,明年 8 月發布的 Go 1.17 將引入
    Go 團隊近日在博客介紹了 Go 泛型的最新進展。Go 團隊表示他們一直在完善泛型的設計草案,並為此編寫了一個類型檢查器——可按照設計草案中的說明,解析使用泛型的 Go 代碼並報告任何類型的錯誤。根據收集的反饋和了解的信息,Go 團隊發布了更新後的泛型設計草案。
  • Java泛型簡單的使用
    Java裡面的泛型在實際開發中運用的很多,學過C++的同學一定知道C++的模板,而Java中的泛型,一定程度上和它還是挺像的。
  • 計算機泛型
    當我們不知道往集合裡面放入什麼數據時候,當這種情況出現時,我們考慮的就是泛型。何為泛型?通俗點說:一個模型,不固定的模型,但我們要提前準備好這個模型,如果對應遊戲裡面的規則的話,就是所謂的預判,我們把這個模型準備了,當我們需要用到的時候,直接使用這個模型改造成自己想要的模樣。
  • Java泛型簡明教程
    儘管有這麼多豐富的資料,有時我感覺,有很多的程式設計師仍然不太明白Java泛型的功用和意義。這就是為什麼我想使用一種最簡單的形式來總結一下程式設計師需要知道的關於Java泛型的最基本的知識。相對於依賴程式設計師來記住對象類型、執行類型轉換——這會導致程序運行時的失敗,很難調試和解決,而編譯器能夠幫助程式設計師在編譯時強制進行大量的類型檢查,發現其中的錯誤。泛型的構成由泛型的構成引出了一個類型變量的概念。
  • Java泛型解析,了解泛型使用
    Java 泛型泛型的本質是參數化類型。簡單解釋就是,將參數的數據類型也當作參數對待。泛型的目的就是為了寫一套代碼,可以到處通用,不用擔心類型安全的問題。泛型可以用在類、接口、方法中對應的就是泛型類、泛型接口和泛型方法。一、為什麼要引入泛型?
  • Hello Go!
    經常看到一堆 err check 代碼夾雜在代碼邏輯裡暫時沒有泛型,某些場景下比較繁瑣生態不夠完善等。Go 還是比較年輕的語言,生態相比一些發展較久的語言還相對欠缺GC,實際上 go 在垃圾回收上比當年改善非常多,web 後端上基本不是個問題總得來說,筆者感覺作為微服務後端語言來說,還是完全夠用的。
  • 掃盲:Kotlin 的泛型
    由於 Java 的泛型本身是一種 「偽泛型」,Java 為了兼容 1.5 以前的版本,不得以在泛型底層實現上使用 Object 引用,所以我們聲明的泛型在編譯時會發生「類型擦除」,泛型類型會被 Object 類型取代。
  • Java泛型的特點與優缺點,泛型擦除是怎麼回事?
    Java 是如何支持泛型的?底層實現?是否了解 Java 泛型的特點,優缺點?是否了解泛型擦除?考察的知識點Java 是如何支持泛型的?底層實現機制是什麼?Java 泛型的特點,泛型優缺點泛型擦除考生應該如何回答1、考生應該首先回答 Java 在 JDK 5 之後引入泛型,Java 為了向下兼容,採用的是偽泛型,Java 虛擬機並不支持泛型。Java 中的泛型和 C++ 中非常類型,但是有著本質的不同。
  • Java面試重要考點攻克:如何在Java中使用泛型?
    正確理解泛型對於掌握Java至關重要,這也會對你的面試有所助益。本文是關於Java中泛型知識的大放送,泛型是什麼,如何在Java中使用,以及它們的優點有哪些,你都能在下文中找到答案。在Java 5中添加泛型是為了提供編譯時類型檢查,並消除使用集合類時常見的 ClassCastException 風險。
  • Java之使用泛型與未使用泛型的區別
    各位小夥伴們大家好,在之前的文章中,小編有介紹過Java之泛型的概念,這次小編要介紹的是,Java程序中,使用泛型與未使用泛型的區別。代碼如下:public class Demo01Generic {public static void main(String[] args) { show01(); show02(); } /*創建集合對象,使用泛型好處:1.避免了類型轉換的麻煩,存儲的是什麼類型的數據,取出的就是什麼類型的數據 2.把運行期異常
  • Java 泛型 T,E,K,V,?,傻傻分不清?
    由於公眾號做了改版,為了保證公眾號的資源能準時推送到你手裡,大家記得將咱們的公眾號加星標置頂,在此真誠的表示感謝~ 正文如下: # 前言 Java 泛型(generics)是 JDK 5 中引入的一個新特性, 泛型提供了編譯時類型安全檢測機制,該機制允許開發者在編譯時檢測到非法的類型
  • Java泛型概念相關面試題匯總.
    答: 泛型是 Java SE 1.5 的新特性,泛型的本質是參數化類型,這種參數類型可以用在類、接口和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。泛型擦除具體來說就是在編譯成字節碼時首先進行類型檢查,接著進行類型擦除(即所有類型參數都用他們的限定類型替換,包括類、變量和方法),接著如果類型擦除和多態性發生衝突時就在子類中生成橋方法解決,接著如果調用泛型方法的返回類型被擦除則在調用該方法時插入強制類型轉換。問:Java 泛型類、泛型接口、泛型方法有什麼區別?
  • Java 泛型詳解-絕對是對泛型方法講解最詳細的,沒有之一
    本文參考java 泛型詳解、Java中的泛型方法、 java泛型詳解概述泛型在java中有很重要的地位,在面向對象編程及各種設計模式中有非常廣泛的應用。什麼是泛型?為什麼要使用泛型?泛型,即「參數化類型」。一提到參數,最熟悉的就是定義方法時有形參,然後調用此方法時傳遞實參。那麼參數化類型怎麼理解呢?
  • Java泛型總結
    什麼是泛型泛型是jdk5引入的類型機制,就是將類型參數化,它是早在1999年就制定的jsr14的實現。泛型機制將類型轉換時的類型檢查從運行時提前到了編譯時,使用泛型編寫的代碼比雜亂的使用object並在需要時再強制類型轉換的機制具有更好的可讀性和安全性。