Goland支持泛型了(上機實操)
事情出因
一大早上被一篇公眾號的推文震驚了,Goland竟然支持go的泛型了。據我所知:
Go的泛型不是還在設計草圖嗎?最樂觀估計也要2021年8月份。你說Go語言現在都沒開發(fā)好泛型,你支持這個特性有什么用呢?
帶著好奇心點開推文,沒發(fā)現對泛型的說明,只看到一個Goland對泛型的使用的說明鏈接: https://blog.jetbrains.com/go/2020/11/24/experimenting-with-go-type-parameters-generics-in-goland/,心里怪癢癢的,忍不住點開看了,恍然大悟。
雖然Go并沒有完整實現好泛型,但是卻有個go2go工具的build工具,能把泛型代碼編譯成二進制可執(zhí)行文件。話不多說,試試它。
準備和我的環(huán)境
- 下載現在最新的Goland工具:2020.3
- macos Big Sur 系統(tǒng)
- git version 2.21.0
- 你可能要科學上網
上機實操
大致流程如下:
- 檢出最新的Go代碼的泛型實現的分支
- 編譯該分支得到一些工具,用來支持泛型
- 在Goland里面配置泛型編譯工具
科學拉取go源碼
由于Go的源碼的git倉庫地址是https://go.googlesource.com/go,卻不在GitHub上,這就有點頭疼了。所以前提是你有科學上網工具。
我介紹下我的步驟。
1.查看你本地代理的代理端口,如我的端口是1087,所以我在我讓我的終端也會走代理,因為一般來說科學上網工具只會代理瀏覽器。
export http_proxy=http://127.0.0.1:1087;export https_proxy=http://127.0.0.1:1087;
然后檢出https://go.googlesource.com/go到go-mainline目錄,并切換分支到
git clone https://go.googlesource.com/go go-mainline
3.此時用Goland打開該go源碼,檢出分支dev.go2go。
4.然后為Goland配置些環(huán)境變量
①、在Settings/Preferences | Go | GOROOT, 選擇No SDK
選項
②、在Settings/Preferences | Tools | Terminal, 添加下面的環(huán)境變量:GOROOT_BOOTSTRAP為版本大于1.14的Go sdk(我直接用的是1.15)、CGO_ENABLED=0
5.然后在Goland的控制臺下,進入到源碼的src下,執(zhí)行
bash make.bash
如果你是windows系統(tǒng),那么就用bash.bat
。
然后等待一會兒,你能明顯聽見CPU風扇的聲音。
6.上面工具都編譯好只有,接下來就新建個項目試一下吧,下面我就拋磚引玉了。
上面是我新建的一個項目,如果你的代碼的后綴不是.go2的話請改成.go2,.go2就表示里面用了go2的語法,也就包括了泛型,這里我測試泛型。(看后綴就能看出來官方的決心了,go2一定是會有泛型的)
7.此時還沒完,可以給Goland加個快捷工具,當然也可以不加在命令行執(zhí)行,把go2泛型代碼編譯成二進制文件,到時候我們就可以執(zhí)行該二進制文件查看泛型代碼的結果。
program我這里是Users/shen/go-mainline/go
,這個就是我上面拉取go的源碼編譯得到的。
在這里就會找到這個命令,執(zhí)行他就會獲得編譯好的二進制文件。
8.最后在命令行就能獲得結果。
9.說說我體驗下來Goland的感受:
①、并沒有想象中那么好用,甚至連最簡單的使用都夠嗆,如看我的截圖,它最any
的關鍵字都提示不支持,你說這。。。
②、當我要運行泛型代碼的時候,還需要自己配置編譯工具,這種體驗我覺得就沒必要說支持了吧,難道是我還沒有使用對,可是我明明按照官方的文檔來操作的啊。
說說對泛型的理解
下面是我的泛型測試代碼:
package main import "fmt" type Book struct { Name string Price int } func (x Book) Less(y Book) bool { return y.Price < x.Price } type Lesser[T any] interface { Less(y T) bool } func doSort[T Lesser[T]](a []T) { for i := 0; i < len(a)-1; i++ { for j := i; j < len(a); j++ { if a[i].Less(a[j]) { a[i], a[j] = a[j], a[i] } } } } func main() { a := []Book{ {"Second Book", 2}, {"First Book", 1}, {"Fifth Book", 5}, {"Fourth Book", 4}, {"Sixth Book", 6}, {"Third Book", 3}, {"shen", 8}, } doSort(a) fmt.Println(a) }
Lesser
是Book
實現的接口,所謂泛型就是接口里面可以不把方法的返回參數,請求參數固定死,這個和java的泛型一致,編譯階段是不知道具體參數類型的,只有在運行時才知道具體的參數類型。Lesser
的方法Less(y T) bool
的參數類型是T
,然后Book
實現該方法就要指定具體參數類型了func (x Book) Less(y Book) bool
,這里就是Book
類型。
然后調用方法理解起來和java的泛型意思差不多了:func doSort[T Lesser[T]](a []T)
,下面是我用java實現相同功能的的泛型:
package com.shen.main; public class Main { public static void main(String[] args) { Book[] a = new Book[]{ new Book("Second Book", 2), new Book("First Book", 1), new Book("Fifth Book", 5), new Book("Fourth Book", 4), new Book("Sixth Book", 6), new Book("Third Book", 3) }; doSort(a); for (Book book : a) { System.out.println(book); } } public static <T extends Lesser<T>> void doSort(T[] a) { for (int i = 0; i < a.length; i++) { for (int j = i; j < a.length; j++) { if (a[i].Less(a[j])) { T temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } } interface Lesser<T> { boolean Less(T y); } class Book implements Lesser<Book> { String name; int price; public Book(String name, int price) { this.name = name; this.price = price; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price=" + price + '}'; } @Override public boolean Less(Book y) { return y.price < this.price; } }
大家對照下看看,是不是和java的何其相似,所以我覺得網上有些人一邊期盼著泛型能徹底改變go的大型工程結構,一邊又怕泛型引來一些維護成本,覺得增加了go的難度。我覺得這個擔心完全沒必要,只要你對java的泛型或者其他語言的泛型稍微有點基礎,就很容易看懂,所有泛型的目的都差不多,只不過是換湯不換藥而已(看到有些人還在爭論go的泛型是用尖括號還是小括號還是中括號而引發(fā)的感嘆)。
總結
好了以上就是我對Goland的泛型支持的體驗過程,對Goland的泛型支持很失望,也許一開始就抱有了很好的期待了吧,但是對Goland的行動很佩服,我相信在Go的泛型正式實現之后,Goland一定會很好的支持的。
還有就是體驗了下泛型的力量,確實減少了很多工作量,代碼更簡潔。留給大家想想: 如果不用泛型go的代碼怎么實現,有多臃腫呢?起碼Lesser
接口里面的方法要為每個具體入參定義一個方法,而且方法名還不能一樣,尼瑪。。。,最最重要的是解耦性還不好:接口耦合了具體參數類型。。。
上面就是我的感受,我也就是入個門,還沒有更加深入的體驗go的泛型草圖設計,如果你也感興趣的話,可以看看go的泛型設計文檔:https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md
到此這篇關于Goland支持泛型了(上機實操)的文章就介紹到這了,更多相關Goland泛型內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
golang跳轉語句goto,break,continue的使用及區(qū)別說明
這篇文章主要介紹了golang跳轉語句goto,break,continue的使用及區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12在Visual Studio Code中配置GO開發(fā)環(huán)境的詳細教程
這篇文章主要介紹了在Visual Studio Code中配置GO開發(fā)環(huán)境的詳細教程,需要的朋友可以參考下2017-02-02