Goland支持泛型了(上機(jī)實(shí)操)
事情出因
一大早上被一篇公眾號(hào)的推文震驚了,Goland竟然支持go的泛型了。據(jù)我所知:
Go的泛型不是還在設(shè)計(jì)草圖嗎?最樂(lè)觀估計(jì)也要2021年8月份。你說(shuō)Go語(yǔ)言現(xiàn)在都沒(méi)開(kāi)發(fā)好泛型,你支持這個(gè)特性有什么用呢?
帶著好奇心點(diǎn)開(kāi)推文,沒(méi)發(fā)現(xiàn)對(duì)泛型的說(shuō)明,只看到一個(gè)Goland對(duì)泛型的使用的說(shuō)明鏈接: https://blog.jetbrains.com/go/2020/11/24/experimenting-with-go-type-parameters-generics-in-goland/,心里怪癢癢的,忍不住點(diǎn)開(kāi)看了,恍然大悟。
雖然Go并沒(méi)有完整實(shí)現(xiàn)好泛型,但是卻有個(gè)go2go工具的build工具,能把泛型代碼編譯成二進(jìn)制可執(zhí)行文件。話不多說(shuō),試試它。
準(zhǔn)備和我的環(huán)境
- 下載現(xiàn)在最新的Goland工具:2020.3
- macos Big Sur 系統(tǒng)
- git version 2.21.0
- 你可能要科學(xué)上網(wǎng)
上機(jī)實(shí)操
大致流程如下:
- 檢出最新的Go代碼的泛型實(shí)現(xiàn)的分支
- 編譯該分支得到一些工具,用來(lái)支持泛型
- 在Goland里面配置泛型編譯工具
科學(xué)拉取go源碼
由于Go的源碼的git倉(cāng)庫(kù)地址是https://go.googlesource.com/go,卻不在GitHub上,這就有點(diǎn)頭疼了。所以前提是你有科學(xué)上網(wǎng)工具。
我介紹下我的步驟。
1.查看你本地代理的代理端口,如我的端口是1087,所以我在我讓我的終端也會(huì)走代理,因?yàn)橐话銇?lái)說(shuō)科學(xué)上網(wǎng)工具只會(huì)代理瀏覽器。
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.此時(shí)用Goland打開(kāi)該go源碼,檢出分支dev.go2go。


4.然后為Goland配置些環(huán)境變量
①、在Settings/Preferences | Go | GOROOT, 選擇No SDK 選項(xiàng)
②、在Settings/Preferences | Tools | Terminal, 添加下面的環(huán)境變量:GOROOT_BOOTSTRAP為版本大于1.14的Go sdk(我直接用的是1.15)、CGO_ENABLED=0


5.然后在Goland的控制臺(tái)下,進(jìn)入到源碼的src下,執(zhí)行
bash make.bash
如果你是windows系統(tǒng),那么就用bash.bat。
然后等待一會(huì)兒,你能明顯聽(tīng)見(jiàn)CPU風(fēng)扇的聲音。
6.上面工具都編譯好只有,接下來(lái)就新建個(gè)項(xiàng)目試一下吧,下面我就拋磚引玉了。

上面是我新建的一個(gè)項(xiàng)目,如果你的代碼的后綴不是.go2的話請(qǐng)改成.go2,.go2就表示里面用了go2的語(yǔ)法,也就包括了泛型,這里我測(cè)試泛型。(看后綴就能看出來(lái)官方的決心了,go2一定是會(huì)有泛型的)
7.此時(shí)還沒(méi)完,可以給Goland加個(gè)快捷工具,當(dāng)然也可以不加在命令行執(zhí)行,把go2泛型代碼編譯成二進(jìn)制文件,到時(shí)候我們就可以執(zhí)行該二進(jìn)制文件查看泛型代碼的結(jié)果。
program我這里是Users/shen/go-mainline/go,這個(gè)就是我上面拉取go的源碼編譯得到的。

在這里就會(huì)找到這個(gè)命令,執(zhí)行他就會(huì)獲得編譯好的二進(jìn)制文件。

8.最后在命令行就能獲得結(jié)果。

9.說(shuō)說(shuō)我體驗(yàn)下來(lái)Goland的感受:
①、并沒(méi)有想象中那么好用,甚至連最簡(jiǎn)單的使用都?jí)騿埽缈次业慕貓D,它最any的關(guān)鍵字都提示不支持,你說(shuō)這。。。
②、當(dāng)我要運(yùn)行泛型代碼的時(shí)候,還需要自己配置編譯工具,這種體驗(yàn)我覺(jué)得就沒(méi)必要說(shuō)支持了吧,難道是我還沒(méi)有使用對(duì),可是我明明按照官方的文檔來(lái)操作的啊。
說(shuō)說(shuō)對(duì)泛型的理解
下面是我的泛型測(cè)試代碼:
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實(shí)現(xiàn)的接口,所謂泛型就是接口里面可以不把方法的返回參數(shù),請(qǐng)求參數(shù)固定死,這個(gè)和java的泛型一致,編譯階段是不知道具體參數(shù)類型的,只有在運(yùn)行時(shí)才知道具體的參數(shù)類型。Lesser的方法Less(y T) bool的參數(shù)類型是T,然后Book實(shí)現(xiàn)該方法就要指定具體參數(shù)類型了func (x Book) Less(y Book) bool,這里就是Book類型。
然后調(diào)用方法理解起來(lái)和java的泛型意思差不多了:func doSort[T Lesser[T]](a []T),下面是我用java實(shí)現(xiàn)相同功能的的泛型:
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;
}
}
大家對(duì)照下看看,是不是和java的何其相似,所以我覺(jué)得網(wǎng)上有些人一邊期盼著泛型能徹底改變go的大型工程結(jié)構(gòu),一邊又怕泛型引來(lái)一些維護(hù)成本,覺(jué)得增加了go的難度。我覺(jué)得這個(gè)擔(dān)心完全沒(méi)必要,只要你對(duì)java的泛型或者其他語(yǔ)言的泛型稍微有點(diǎn)基礎(chǔ),就很容易看懂,所有泛型的目的都差不多,只不過(guò)是換湯不換藥而已(看到有些人還在爭(zhēng)論go的泛型是用尖括號(hào)還是小括號(hào)還是中括號(hào)而引發(fā)的感嘆)。
總結(jié)
好了以上就是我對(duì)Goland的泛型支持的體驗(yàn)過(guò)程,對(duì)Goland的泛型支持很失望,也許一開(kāi)始就抱有了很好的期待了吧,但是對(duì)Goland的行動(dòng)很佩服,我相信在Go的泛型正式實(shí)現(xiàn)之后,Goland一定會(huì)很好的支持的。
還有就是體驗(yàn)了下泛型的力量,確實(shí)減少了很多工作量,代碼更簡(jiǎn)潔。留給大家想想: 如果不用泛型go的代碼怎么實(shí)現(xiàn),有多臃腫呢?起碼Lesser接口里面的方法要為每個(gè)具體入?yún)⒍x一個(gè)方法,而且方法名還不能一樣,尼瑪。。。,最最重要的是解耦性還不好:接口耦合了具體參數(shù)類型。。。
上面就是我的感受,我也就是入個(gè)門(mén),還沒(méi)有更加深入的體驗(yàn)go的泛型草圖設(shè)計(jì),如果你也感興趣的話,可以看看go的泛型設(shè)計(jì)文檔:https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md
到此這篇關(guān)于Goland支持泛型了(上機(jī)實(shí)操)的文章就介紹到這了,更多相關(guān)Goland泛型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言實(shí)現(xiàn)JSON解析的方法詳解
在日常項(xiàng)目中,使用Json格式進(jìn)行數(shù)據(jù)封裝是比較常見(jiàn)的操作。本文將詳細(xì)講解如何利用Go語(yǔ)言實(shí)現(xiàn)JSON的解析,感興趣的小伙伴可以學(xué)習(xí)一下2022-04-04
Golang 使用接口實(shí)現(xiàn)泛型的方法示例
這篇文章主要介紹了Golang 使用接口實(shí)現(xiàn)泛型的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
Golang極簡(jiǎn)入門(mén)教程(二):方法和接口
這篇文章主要介紹了Golang極簡(jiǎn)入門(mén)教程(二):方法和接口,本文同時(shí)講解了錯(cuò)誤、匿名域等內(nèi)容,需要的朋友可以參考下2014-10-10
golang連接kafka消費(fèi)進(jìn)ES操作
這篇文章主要介紹了golang連接kafka消費(fèi)進(jìn)ES操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
解決老版本goland無(wú)法調(diào)試新版本go的問(wèn)題
這篇文章主要給大家介紹了如何解決老版本goland無(wú)法調(diào)試新版本go的問(wèn)題,文中通過(guò)代碼示例給大家講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-11-11
一文教你學(xué)會(huì)Go中singleflight的使用
緩存在項(xiàng)目中使用應(yīng)該是非常頻繁的,提到緩存只要了解過(guò)?singleflight?,基本都會(huì)用于緩存實(shí)現(xiàn)的一部分吧,下面就跟隨小編一起來(lái)學(xué)習(xí)一下singleflight的使用吧2024-02-02
golang跳轉(zhuǎn)語(yǔ)句goto,break,continue的使用及區(qū)別說(shuō)明
這篇文章主要介紹了golang跳轉(zhuǎn)語(yǔ)句goto,break,continue的使用及區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
Go到底能不能實(shí)現(xiàn)安全的雙檢鎖(推薦)
這篇文章主要介紹了Go到底能不能實(shí)現(xiàn)安全的雙檢鎖,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
Golang切片連接成字符串的實(shí)現(xiàn)示例
本文主要介紹了Golang切片連接成字符串的實(shí)現(xiàn)示例,可以使用Go語(yǔ)言中的內(nèi)置函數(shù)"String()"可以將字節(jié)切片轉(zhuǎn)換為字符串,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
在Visual Studio Code中配置GO開(kāi)發(fā)環(huán)境的詳細(xì)教程
這篇文章主要介紹了在Visual Studio Code中配置GO開(kāi)發(fā)環(huán)境的詳細(xì)教程,需要的朋友可以參考下2017-02-02

