目錄
CR標準做法
Receiver是方法的第一個參數!
Receiver是可以为nil的!!!
首頁 後端開發 Golang 為什麼go中的receiver name不推薦使用this或self

為什麼go中的receiver name不推薦使用this或self

Jul 21, 2023 pm 01:23 PM
go

在日常的開發中我們除了定義函數以外, 我們也會定義一些方法。這本來沒有什麼, 但是一些從PHP或其他物件導向語言轉GO的同學往往會把receiver name命名為thisself#, me等。

筆者在實際專案開發中也遇到類似的同學, 屢次提醒卻沒有效果,於是決心寫下這篇文章以便好好說服這些同學。

CR標準做法

首先我們來看看GO建議的標準命名Receiver Names,以下內容摘錄自https://github.com/golang/go/wiki/CodeReviewComments #receiver-names:

The name of a method's receiver should be a reflection of its identity;
often a one or two letter abbreviation of its type suffices (such as "c" or "cl" for "Client").
Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that gives the method a special meaning.
In Go, the receiver of a method is just another parameter and therefore, should be named accordingly.
...
登入後複製

簡單翻譯總結有以下2點:

  1. 方法接受者名稱應反映其身份,並且不要使用methisself這些物件導向語言的典型標誌符。

  2. 在go中方法接受者其實就是方法的另一個參數。

Receiver是方法的第一個參數!

上面的第二點, 可能不是很好理解,所以我們直接看下面的demo:

// T ...
type T int

// Println ...
func (t T) Println() {
	fmt.Println("value: %v", t)
}

func main() {
	t := T(1)
	t.Println()

	T.Println(t)
// receiver作为函数的第一个参数,这个时候发生值拷贝,所以方法内部的t变量是真实t变量的一个拷贝
// 这和this的含义是不相符的

}
// output:
value: 1
value: 1
登入後複製

通过上面的demo, 我们知道接受者可以直接作为第一个参数传递给方法的。而t.Println()应该就是Go中的一种语法糖了。

到这里可能有同学又要问了, 既然Go提供了这种语法糖,那我们这样命名有什么问题呢?笔者先不着急解释, 我们继续看下面的demo:

// Test ...
type Test struct {
	A int
}

// SetA ...
func (t Test) SetA(a int) {
	t.A = a
}

// SetA1 ...
func (t *Test) SetA1(a int) {
	t.A = a
}

func main() {
	t := Test{
		A: 3,
	}
	fmt.Println("demo1:")
	fmt.Println(t.A)
	t.SetA(5)
	fmt.Println(t.A)
	t1 := Test{
		A: 4,
	}
	fmt.Println("demo2:")
	fmt.Println(t1.A)
	(&t1).SetA1(6)
	fmt.Println(t1.A)
}
// output:
demo1:
3
3
demo2:
4
6
登入後複製

看上面的demo我们知道, 当receiver不是指针时调用SetA其值根本没有改变。

因为Go中都是值传递,所以你如果对SetA的receiver的名称命名为this, self等,它就已经失去了本身的意义——“调用一个对象的方法就是向该对象传递一条消息”。而且对象本身的属性也并不一定会发生改变。

综上: 请各位读者在对receiver命名时不要再用this, self等具有特殊含义的名称啦。

Receiver是可以为nil的!!!

最近在研读h2_bundle.go的时候,发现了一段特殊的代码,顿时惊出一身冷汗,姑在本文补充一下,以防止自己和各位读者踩坑。

源代码截图如下: 為什麼go中的receiver name不推薦使用this或self

惊出我一身冷汗的正是图中标红的部分,receiver居然还要判断为nil!在我的潜意识里一直是这样认为的,receiver默认都是有值的,直接使用就行了。这简直颠覆我的认知,吓得我赶紧写了个demo验证一下:

type A struct {
	v int
}

func (a *A) test() {
	fmt.Println(a == nil)
}

func (a *A) testV() {
	fmt.Println(a.v)
}


func main() {
var a *A
	a.test()
	a.testV()
}
登入後複製

上述输出如下:

為什麼go中的receiver name不推薦使用this或self

a.test()能夠正常輸出,只有在處理變數結構體內部變數v才報出panic! ! !還好本文前面已經介紹了Receiver是方法的第一個參數。正因為是第一個參數所以僅僅作為參數傳遞時即使是nil也能夠正常調用函數,而在真正使用的地方報出panic。

以上是為什麼go中的receiver name不推薦使用this或self的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
Go WebSocket 訊息如何發送? Go WebSocket 訊息如何發送? Jun 03, 2024 pm 04:53 PM

在Go中,可以使用gorilla/websocket包發送WebSocket訊息。具體步驟:建立WebSocket連線。傳送文字訊息:呼叫WriteMessage(websocket.TextMessage,[]byte("訊息"))。發送二進位訊息:呼叫WriteMessage(websocket.BinaryMessage,[]byte{1,2,3})。

如何在 Go 中使用正規表示式匹配時間戳記? 如何在 Go 中使用正規表示式匹配時間戳記? Jun 02, 2024 am 09:00 AM

在Go中,可以使用正規表示式比對時間戳記:編譯正規表示式字串,例如用於匹配ISO8601時間戳記的表達式:^\d{4}-\d{2}-\d{2}T \d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ 。使用regexp.MatchString函數檢查字串是否與正規表示式相符。

Golang 與 Go 語言的區別 Golang 與 Go 語言的區別 May 31, 2024 pm 08:10 PM

Go和Go語言是不同的實體,具有不同的特性。 Go(又稱Golang)以其並發性、編譯速度快、記憶體管理和跨平台優點而聞名。 Go語言的缺點包括生態系統不如其他語言豐富、文法更嚴格、缺乏動態類型。

Golang 技術效能優化中如何避免記憶體洩漏? Golang 技術效能優化中如何避免記憶體洩漏? Jun 04, 2024 pm 12:27 PM

記憶體洩漏會導致Go程式記憶體不斷增加,可通過:關閉不再使用的資源,如檔案、網路連線和資料庫連線。使用弱引用防止記憶體洩漏,當物件不再被強引用時將其作為垃圾回收目標。利用go協程,協程棧記憶體會在退出時自動釋放,避免記憶體洩漏。

Golang 函數接收 map 參數時的注意事項 Golang 函數接收 map 參數時的注意事項 Jun 04, 2024 am 10:31 AM

在Go中傳遞map給函數時,預設會建立副本,對副本的修改不影響原map。如果需要修改原始map,可透過指標傳遞。空map需小心處理,因為技術上是nil指針,傳遞空map給期望非空map的函數會發生錯誤。

如何使用 Golang 的錯誤包裝器? 如何使用 Golang 的錯誤包裝器? Jun 03, 2024 pm 04:08 PM

在Golang中,錯誤包裝器允許你在原始錯誤上追加上下文訊息,從而創建新錯誤。這可用於統一不同程式庫或元件拋出的錯誤類型,簡化偵錯和錯誤處理。步驟如下:使用errors.Wrap函數將原有錯誤包裝成新錯誤。新錯誤包含原始錯誤的上下文資訊。使用fmt.Printf輸出包裝後的錯誤,提供更多上下文和可操作性。在處理不同類型的錯誤時,使用errors.Wrap函數統一錯誤類型。

如何在 Go 中創建優先級 Goroutine? 如何在 Go 中創建優先級 Goroutine? Jun 04, 2024 pm 12:41 PM

在Go語言中建立優先權Goroutine有兩步驟:註冊自訂Goroutine建立函數(步驟1)並指定優先權值(步驟2)。這樣,您可以建立不同優先順序的Goroutine,優化資源分配並提高執行效率。

如何在 Golang 單元測試中使用 gomega 進行斷言? 如何在 Golang 單元測試中使用 gomega 進行斷言? Jun 05, 2024 pm 10:48 PM

如何在Golang單元測試中使用Gomega進行斷言在Golang單元測試中,Gomega是一個流行且功能強大的斷言庫,它提供了豐富的斷言方法,使開發人員可以輕鬆驗證測試結果。安裝Gomegagoget-ugithub.com/onsi/gomega使用Gomega進行斷言以下是使用Gomega進行斷言的一些常用範例:1.相等斷言import"github.com/onsi/gomega"funcTest_MyFunction(t*testing.T){

See all articles