golang結構體方法隱式呼叫

2021-10-08 04:00:38 字數 2362 閱讀 1420

方法是golang中的乙個特性,方法可以看作是帶有特殊接受者引數的函式,最常用的是為結構體定義方法,看起來就像物件導向裡邊的物件下的方法

package main

import

("fmt"

)type book struct

func

(b book)

setpages()

func

(b *book)

pages()

如示例,是為book型別定義了setpages方法、為*book型別定義了pages方法,既可以為指標定義方法,也可以為值型別定義方法,方法是帶有特殊接收者引數的函式,所以上邊定義與如下是相同的:

func  book.

setpages

(b book)

func

(*book)

.pages()

但是在定義時是不合法的,沒法這麼定義,但是我們可以顯式呼叫隱式定義

func

(b book)

setpages()

func

(b *book)

pages()

func

main()

呼叫方法時我們可以像物件導向呼叫物件下的方法一樣,使用v.m的形式

type book struct

func

(b book)

setpages()

func

(b *book)

pages()

func

main()

b1 :=

&b b.

setpages()

// setpages

b1.setpages()

// setpages

b.pages()

// pages

b1.pages()

// pages

}

為什麼可以使用指標呼叫setpages方法、值型別呼叫pages方法呢?並沒有為指標定義setpages方法,也沒有為值定義pages方法啊。

原因在於golang為了方便,在設計的時候有考慮到,實際在使用指標呼叫setpages方法時,golang會將其解釋為*b1.setpages()在使用值型別呼叫pages方法時,golang會將其解釋為&b.pages()

如果我們這樣寫呢?

func

(b book)

setpages()

func

(b *book)

pages()

func

main()

).setpages()

// setpages

(&book).

setpages()

// setpages

(&book).

pages()

// pages

(book).

pages()

// 報錯

}

會發現呼叫(book{}).pages()會報錯:

.\default.go

:23:10

: cannot call pointer method on book literal

不能在字面量上呼叫指標方法,為什麼不可以呢?和用變數呼叫的區別在哪呢?

原因在於當接收者引數為指標型別時,接受者必須為可定址的值型別,字面量結構體就是不可定址的

func

main()

).setpages()

// setpages

(&book).

setpages()

// setpages

(&book).

pages()

// pages

fmt.

printf

(, book

)}

返回值不是乙個位址

在golang種具有&t{}語法糖,與temp:=t{};(&temp)相同,所以&t{}可定址不代表t{}可定址

golang不可定址

go101

以下情況可取位址操作

變數可定址的陣列元素

可定址的結構體欄位

切片指標引用

golang結構體方法隱式呼叫

方法是golang中的乙個特性,方法可以看作是帶有特殊接受者引數的函式,最常用的是為結構體定義方法,看起來就像物件導向裡邊的物件下的方法 package main import fmt type book struct func b book setpages func b book pages 如...

golang結構體與方法

type people inte ce type student struct func stu student speak think string talk string else return func main think speak fmt.println peo.speak think ...

Golang基礎 結構體 方法

type 結構體名稱 structtype people structvar peo people fmt.print peo 輸出 fmt.printf p peo 會列印記憶體位址值var peo people 按照結構體中屬性的順序進行賦值,可以省略屬性名稱 peo people fmt.pr...