ホームページ >バックエンド開発 >Golang >Go言語で構造体メソッドを定義する方法

Go言語で構造体メソッドを定義する方法

青灯夜游
青灯夜游オリジナル
2023-01-17 14:06:412638ブラウズ

Go 言語で構造体メソッドを定義する方法: 1. 構文 "type point struct {....}" で構造体を定義します; 2. 構造体をレシーバーとして使用して、構造体メソッドを定義します。 「func(レシーバ変数レシーバ型)メソッド名(パラメータ一覧)(戻り値一覧) {//メソッド本体}」。 Go 言語では、レシーバーの型は構造体だけでなく、構造体型以外の任意の型を使用できます。

Go言語で構造体メソッドを定義する方法

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

構造メソッド

Go言語には関数とメソッドの両方があり、メソッドの本質は関数ですが、メソッドと関数は異なる点があります。

関数 関数は、コードの再利用を実現するために複数回呼び出すことができる独立した関数を持つコードの一部です。

Method メソッドはクラスの動作関数であり、このクラスのオブジェクトによってのみ呼び出すことができます。

Go 言語のメソッドは、特定の型の変数に作用する関数です。この特定のタイプの関数は Receiver と呼ばれます。レシーバーの概念は、オブジェクト指向言語の this または self キーワードに似ています。

Go 言語の受容者は、メソッドにはアクション オブジェクトがあるが、関数にはアクション オブジェクトがないことが強調されています。

Go 言語では、レシーバーの型は、構造体だけでなく、構造体型以外の任意の型にすることができます。 (整数、文字列、スライス、マップ、さらには関数など)

受信者が異なる限り、メソッド名は同じであってもかまいません。

オーバーライドされたメソッドはありますが、オーバーロードされたメソッドはありません(オーバーロードされたメソッドはサポートされていません。つまり、同じ名前を持つメソッドで異なるパラメーターは定義できません)

構造体メソッドを定義します

レシーバーは構造体型または非構造体型にすることができます。ポインター型と非構造体型を指定することもできます。 -ポインタ型。

レシーバーで変数に名前を付けるときは、レシーバーの型の最初の小文字を使用することが公式に推奨されています。

// 定义方法的语法格式:
func (接收者变量 接收者类型) 方法名(参数列表) (返回值列表){
    //方法体
}

// 定义结构体
type point struct {
    X int
    Y int
}

// 定义结构体方法
func (p point) print() {
    fmt.Println(p.X, p.Y)
}

ポインタ レシーバ

実パラメータが大きすぎる場合、go 関数は各実パラメータ変数をコピーします。また、引数全体のコピーを避けたい場合は、ポインタを使用して変数のアドレスを渡すことができます。

ポインター レシーバーがメソッドを呼び出すと、コンパイラーは暗黙的に変数を変換します。

type point struct {
    X int
    Y int
}
func (p point) Print() {
    fmt.Println(p.X, p.Y)
}
func (p *point) ScaleBy(factor int) {
    p.X *= factor
    p.Y *= factor
}
func main() {
    p := point{1,1}
    ptr := &p
    p.Print()   //1. 正确
    ptr.Print() //2. 正确
    p.ScaleBy(2)      //3. 正确
    ptr.ScaleBy(2)    //4. 正确
    point{1,1}.Print()    //5. 正确
    (&point{1,1}).Print() //6. 正确
    (&point{1,1}).ScaleBy( 2) //7. 正确
    point{1,1}.ScaleBy( 2)    //8. 错误
}

nil は正当なレシーバーです。一部の関数が実際のパラメーターとして nil ポインターを許可するのと同じように、メソッドのレシーバーでも nil ポインターが許可されます

// 定义结构体
type A struct {
    Data int
}

// 定义结构体方法
func (a *A) FunPtrA() {
    fmt.Println("FunPtrA")
}

func main() {
    
    // 声明结构体变量
    var ptrA *A
    
    // 将 nil 赋值给结构体变量
    ptrA = nil
    
    // 调用结构体方法
    ptrA.FunPtrA()  //FunPtrA
}

メソッドの継承とオーバーライド

// 声明 human 结构体
type human struct {
	name, phone string
	age         int8
}
 
// student 继承 human 结构体 所以继承 human 的方法
type student struct {
	human
	school string
}
 
// employee 继承 human 结构体 所以继承 human 的方法
type employee struct {
	human
	company string
}
 
// human 定义 sayHi 方法
func (h human) sayHi() {
	fmt.Printf("我是%s,年龄%d,联系方式%s \n", h.name, h.age, h.phone)
}


// 方法的继承
func testMethod11(){
        // student 继承 human 所以有 sayHi 方法, employee 同理
	s1 := student{human{"s1","138001",13},"第一中学"}
	e1 := employee{human{"e1","138002",30},"第一企业"}
	s1.sayHi()    //我是s1,年龄13,联系方式138001
	e1.sayHi()    //我是e1,年龄30,联系方式138002
}


// 方法的重写 此为重写 非重载
func (s student) sayHi(){
	fmt.Printf("我是%s,年龄%d,我在%s上学,联系方式%s \n", s.name, s.age, s.school,s.phone)
}
 
func testMethod12(){
	s1 := student{human{"s1","138001",13},"第一中学"}
	s1.sayHi()    //我是s1,年龄13,我在第一中学上学,联系方式138001
}

プロセス指向とオブジェクト指向

//面向过程
func Add01(a, b int) int {
	return a + b
}
 
//面向对象,方法:给某个类型绑定一个函数
type long int
 
//tmp叫接收者,接收者就是传递的一个参数
func (tmp long) Add02(other long) long  {
	return tmp + other
}
 
func main() {
	var result int
	result = Add01(1, 2) //普通函数调用方式
	fmt.Println("result = ", result)
 
	//定义一个变量
	var a long = 2
	//调用方式格式: 变量名,函数(所需参数)
	r := a.Add02(2)
	fmt.Println("r = ", r)
 
}

[関連する推奨事項: Go ビデオ チュートリアル プログラミング教育 ]

以上がGo言語で構造体メソッドを定義する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。