久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

手機(jī)站
千鋒教育

千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

千鋒教育

掃一掃進(jìn)入千鋒手機(jī)站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學(xué)習(xí)站小程序
隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

當(dāng)前位置:首頁  >  技術(shù)干貨  > 使用具名返回值巧妙解決泛型函數(shù)返回零值的問題

使用具名返回值巧妙解決泛型函數(shù)返回零值的問題

來源:千鋒教育
發(fā)布人:qyf
時(shí)間: 2022-08-04 16:17:00 1659601020

使用具名返回值巧妙解決泛型函數(shù)返回零值的問題

  Go語言泛型語法特性在Go 1.18版本落地后,不出所料,在github上看到大量的基礎(chǔ)容器類型數(shù)據(jù)結(jié)構(gòu)被用泛型重寫。這種重寫我覺得是很正常、很自然的,并且實(shí)現(xiàn)良好的通用數(shù)據(jù)結(jié)構(gòu)改為泛型其實(shí)也不難,有些簡(jiǎn)單的結(jié)構(gòu)可能分分鐘就能搞定。

  Go 1.18發(fā)布后,我一直沒機(jī)會(huì)寫泛型,今天在做DSL語義模型提取時(shí),多處用到Stack結(jié)構(gòu),于是想到使用泛型簡(jiǎn)單實(shí)現(xiàn)了一個(gè)通用的Stack結(jié)構(gòu)。

  在Go中,我們可以用一個(gè)切片來定義Stack。泛型Stack類型的定義如下:

  type Stack[T any] []T

  這里的Stack類型就是一個(gè)帶有類型參數(shù)(type parameter)的泛型類型,它的類型參數(shù)的約束(constraints)為any,即允許任何類型作為Stack的元素類型。

  Stack是最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),一般來說它具有的操作方法包括:

  Push:壓棧;

  Pop:彈棧;

  Top:獲取棧頂元素;

  Len:獲取棧內(nèi)元素個(gè)數(shù)。

  對(duì)于以切片為底層存儲(chǔ)的Stack而言,壓棧Push操作就相當(dāng)于對(duì)切片的追加(append)操作:

  func (s *Stack[T]) Push(v T) {

  (*s) = append((*s), v)

  }

  不過,這里有兩點(diǎn)要注意:

  泛型類型的方法原型中,receiver部分的類型要帶上類型參數(shù),比如這里的*Stack[T];

  這里務(wù)必要用*Stack[T],而不要像下面代碼這樣用Stack[T],否則append方法改變的僅僅是Stack[T]的拷貝,而不是原Stack[T]類型的實(shí)例。

  func (s Stack[T]) Push(v T) {

  s = append(s, v)

  }

  我們?cè)賮砜纯?Stack[T]的彈棧Pop方法:

  func (s *Stack[T]) Pop() T {

  if len(*s) == 0 {

  return nil

  }

  // Get the last element from the stack.

  t := (*s)[len(*s)-1]

  // Remove the last element from the stack.

  *s = (*s)[:len(*s)-1]

  return t

  }

  這樣實(shí)現(xiàn)的Pop方法會(huì)提示return nil一行有錯(cuò)誤:cannot use nil as T value in return statement。Go編譯器錯(cuò)誤信息提示我們:nil不能作為T類型的值返回。

  Stack的類型參數(shù)的約束為any,即Stack的元素可以是任意類型,即可以是切片、map等復(fù)合類型,亦可以是int、string等值類型。如果將nil作為所有這些類型的零值的確不恰當(dāng)。

  那么當(dāng)Stack為空時(shí),應(yīng)該如何返回呢?多虧Go原生支持類型零值。

  我們可以聲明一個(gè)類型零值并將其作為返回值返回:

  func (s *Stack[T]) Pop() T {

  if len(*s) == 0 {

  var zero T

  return zero // 模擬類型零值

  }

  // Get the last element from the stack.

  t := (*s)[len(*s)-1]

  // Remove the last element from the stack.

  *s = (*s)[:len(*s)-1]

  return t

  }

  雖然這種方法有效,但你是不是和我有一樣的感覺:不夠優(yōu)雅。下面我們就來看一個(gè)更為優(yōu)雅的小技巧:利用函數(shù)的具名返回值,看代碼:

  func (s *Stack[T]) Pop() (t T) {

  if len(*s) == 0 {

  return

  }

  // Get the last element from the stack.

  t = (*s)[len(*s)-1]

  // Remove the last element from the stack.

  *s = (*s)[:len(*s)-1]

  return

  }

  我們看到:具名返回值(named return value)一出馬,一切都變得自然而然了。當(dāng)然這也要?dú)w功于Go的類型零值特性。

  具名返回值日常使用的不多,從使用的頻度來看,Go標(biāo)準(zhǔn)庫(kù)以及多數(shù)項(xiàng)目的代碼默認(rèn)選擇非具名返回值(unamed return value)。當(dāng)函數(shù)使用defer且在deferred函數(shù)中修改外部函數(shù)返回值時(shí),應(yīng)用具名返回值可以讓代碼顯得更清晰一些:

  func Foo() (a int) {

  defer func() {

  a = 5

  }

  a = 6

  }

  其他情況,看項(xiàng)目編碼規(guī)范一致性要求以及個(gè)人喜好了。不過,Go引入泛型后,針對(duì)上述的泛型函數(shù)返回零值的情況,相信具名返回值將得到更多的“出鏡”的機(jī)會(huì)。

  更多關(guān)于“java培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學(xué),課程大綱緊跟企業(yè)需求,更科學(xué)更嚴(yán)謹(jǐn),每年培養(yǎng)泛IT人才近2萬人。不論你是零基礎(chǔ)還是想提升,都可以找到適合的班型,千鋒教育隨時(shí)歡迎你來試聽。

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
免費(fèi)領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學(xué) 138****2860 剛剛成功領(lǐng)取
王同學(xué) 131****2015 剛剛成功領(lǐng)取
張同學(xué) 133****4652 剛剛成功領(lǐng)取
李同學(xué) 135****8607 剛剛成功領(lǐng)取
楊同學(xué) 132****5667 剛剛成功領(lǐng)取
岳同學(xué) 134****6652 剛剛成功領(lǐng)取
梁同學(xué) 157****2950 剛剛成功領(lǐng)取
劉同學(xué) 189****1015 剛剛成功領(lǐng)取
張同學(xué) 155****4678 剛剛成功領(lǐng)取
鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
董同學(xué) 138****2867 剛剛成功領(lǐng)取
周同學(xué) 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
服務(wù)器為什么要用Linux?

服務(wù)器為什么要用Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,Linux在眾多選擇中脫穎而出。Linux作為服務(wù)器操作系統(tǒng)的優(yōu)選,有其獨(dú)特的優(yōu)勢(shì)和特點(diǎn)。包括其...詳情>>

2023-10-14 12:34:11
ORM解決的主要問題是什么?

ORM(對(duì)象關(guān)系映射)解決的主要問題是將關(guān)系數(shù)據(jù)庫(kù)與面向?qū)ο缶幊讨g的映射困境。在傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)中,數(shù)據(jù)以表格的形式存儲(chǔ),而在面向?qū)ο?..詳情>>

2023-10-14 12:26:19
Go為什么不支持三元運(yùn)算符?

Go為什么不支持三元運(yùn)算符Go語言是一種以簡(jiǎn)潔和有效性為目標(biāo)的編程語言,因此在設(shè)計(jì)過程中,Go的設(shè)計(jì)者刻意排除了一些他們認(rèn)為可能導(dǎo)致復(fù)雜性或...詳情>>

2023-10-14 12:12:36
IT通常說的平臺(tái)是什么意思?

在信息技術(shù)(IT)領(lǐng)域,”平臺(tái)”這個(gè)詞有著廣泛的含義,它常常指代支持軟件應(yīng)用開發(fā)和運(yùn)行的基礎(chǔ)框架和環(huán)境。以下是對(duì)”平臺(tái)”這個(gè)概念的更深入...詳情>>

2023-10-14 11:55:36
什么是PowerPivot?

什么是PowerPivotPowerPivot,全稱”PowerPivot for Excel”,是Microsoft提供的一種數(shù)據(jù)分析工具,可以作為Excel的插件使用。通過PowerPivot,...詳情>>

2023-10-14 11:25:48