GO 方法學習筆記

Pon發表於2020-04-13

方法的定義

func (recevier type) methodName(引數列表) (返回值列表){
    方法體
    return 返回值
}

方法的使用

  1. 方法需要個定義的型別進行繫結
    type Person struct {
     Name string
    }
    func (p Person)testMothod(){ //繫結P型別
     fmt.Println("Name =",p.Name)
    }
    func main()  {
     person := Person{Name:"jack"}
     person.testMothod()
    }
  2. golang中的方法是作用在指定的資料型別上的(即:和指定的資料型別繫結),因此自定義型別,都可以有方法,而不僅僅是struct
    例如:type number int
    number 也是可以繫結方法的
  3. 方法只能通過定義的型別的變數來呼叫,而不能直接呼叫,也不能使用其他型別變數來呼叫
    type Person struct {
     Name string
    }
    type Car struct {
     Price int
    }
    func (p Person)testMothod(){
     fmt.Println("Name =",p.Name)
    }
    func main()  {
     //正確呼叫
     person := Person{Name:"jack"}
     person.testMothod()
     //錯誤呼叫
     car := Car{Price:5000000}
     car.testMothod() //只能使用Person型別呼叫,使用Car呼叫就會報錯
    }

    方法和函式的區別

  4. 呼叫方式不一樣
    函式呼叫方式:函式名(實參列表)
    方法呼叫方式: 變數.方法名(實參列表)

程式碼:

package main
import (
"fmt"
)
type Person struct {
    Name string
}
//函式
func testFunc(p Person){
    fmt.Println("函式中的Name = ",p.Name)
}
//方法
func (p Person) testMethod(){
    fmt.Println("方法中的Name = ",p.Name)
}
func main(){
    //函式呼叫方式
    person := Person{Name:"Jack"}
    testFunc(person)
    //方法呼叫方式
    person.Name = "Pon"
    person.testMethod()
}

執行結果:

GO 方法詳解

2.對於普通函式,接收則為值型別時,不能將指標型別的資料直接傳遞,反之亦然

type Person struct {
    Name string
}

func testFunc01(p Person){
    fmt.Println("函式中的Name = ",p.Name)
}

func testFunc02(p *Person){
    fmt.Println("函式中的Name = ",p.Name)
}

func main(){
    //函式呼叫
    person := Person{Name:"Jack"}
    testFunc01(person)
    testFunc02(&person)  //這裡如果testFunc02(person) 這樣呼叫就會報錯
}

3.對於方法(如struct的方法),接收者為值型別時,可以直接用指標型別的變數呼叫方法,反過來同樣也可以

type Person struct {
    Name string
}
func (p Person) testMethod01(){
    fmt.Println("方法中的Name = ",p.Name)
}
func (p *Person) testMethod02(){
    fmt.Println("方法中的Name = ",p.Name)
}
func main(){
    //方法呼叫
    person := Person{Name:"Jack"}
    person.testMethod01()  //這裡 person.testMethod01() 和 (&person).testMethod01() 呼叫都是一樣的,都是值拷貝
    (&person).testMethod02()  //這裡 person.testMethod02() 和 (&person).testMethod02() 呼叫都是一樣的,都是地址拷貝
}

總結:
不管呼叫形式如何,真正決定是值拷貝還是地址拷貝,看這個方法和那個型別繫結。
如果是和值型別,比如(p Person),則是值拷貝,如果和指標型別,比如(p *Person)則是地址拷貝

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章