1. 程式人生 > 實用技巧 >值型別、指標型別接收器和介面型別賦值總結

值型別、指標型別接收器和介面型別賦值總結

值接收器和指標接收器

package main

import "fmt"

type stu struct {
	Name string
	Age  int
}

func (s stu) changeName(name string) {
	s.Name = name
}

func (s *stu) changeAge(age int) {
	s.Age = age
}

func main() {
	student := stu{
		Name: "a",
		Age:  0,
	}

	fmt.Println("原始資料", student)

	student.changeName("b")
	student.changeAge(10)
	fmt.Println("結構體變數傳遞", student)

	//var ptr *stu = &student
	(&student).changeName("c")
	(&student).changeAge(20)
	fmt.Println("結構體指標傳遞", student)
}
/*
原始資料 {a 0}
結構體變數傳遞 {a 10}
結構體指標傳遞 {a 20}
*/

可以看出對於 指標型別接收器值型別接收器 的函式,可以使用 指標型別呼叫 也可以使用 值型別呼叫 。並且只要呼叫了指標型別的接收器,不管是值型別進行的呼叫還是指標型別進行的呼叫,都可以對資料進行修改;相反,呼叫了值型別接收器,不管是值型別進行的呼叫還是指標型別進行的呼叫,都不能對資料進行修改。

關於介面型別接收具體型別

package main

import "fmt"

type Animal interface {
	say()
}

type dog struct {
	Name string
}

func (d *dog) say() {
	fmt.Println("汪汪汪")
}

type cat struct {
	Name string
}

func (c cat) say() {
	fmt.Println("喵喵喵")
}

func main() {
	dog := dog{Name: "dog"}
	cat := cat{Name: "cat"}

	/*Cannot use 'dog' (type dog) as type introduction Type does not implement 'Animal' as 'say' method has a pointer receiver*/
	//var animal1 Animal = dog // 報錯
	var animal11 Animal = &dog
	//animal1.say()
	animal11.say()

	var animal2 Animal = cat
	var animal22 Animal = &cat
	animal2.say()
	animal22.say()
}
/*
汪汪汪
喵喵喵
喵喵喵
*/

可以看出對於介面用 指標接收器型別 對介面方法實現 ,值型別不可以直接賦給介面型別,也不可以用來呼叫函式,因為它(值型別)其實沒有實現介面(真正實現的是結構體指標型別)。

總結

  • 介面的 指標型別接收器 只能用 指標型別 呼叫。
  • 其他的 指標型別接收器 和 值型別接收器 的函式,可以用指標型別呼叫,也可以用值型別呼叫。