目次
関数
メソッド
Go语言中方法和函数的区别
ホームページ バックエンド開発 Golang Go言語のメソッドと関数の違いは何ですか

Go言語のメソッドと関数の違いは何ですか

Jan 03, 2023 am 11:23 AM
golang 言語を移動

違い: 1. 関数は独立した関数を持つコードの一部であり、コードを再利用するために何度も繰り返し呼び出すことができますが、メソッドはクラスの動作関数であり、そのクラスのオブジェクトによってのみ呼び出すことができます。クラス。 。 2. メソッドにはレシーバーがありますが、関数にはレシーバーがありません。 3. 関数には同じ名前を付けることはできませんが、メソッドには同じ名前を付けることができます。 4. 呼び出し方法が異なります。 5. メソッドはその型を指定する必要があります。関数は汎用型ですが、構造体またはカスタム型を指定できます。 6. 関数の形式とパラメータの型は一貫している必要があり、メソッドは変更できます。

Go言語のメソッドと関数の違いは何ですか

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

Go 言語では、関数とメソッドは異なり、概念的に明確な区別があります。 Java など他の言語では、一般に関数はメソッド、メソッドは関数となりますが、Go 言語では関数は構造や型に属さないメソッドを指します。 , 関数にはレシーバーがありません; メソッドにはレシーバーがあります ここで話しているメソッドは、構造体に属しているか、新しく定義された型に属しているかのいずれかです。

関数

関数とメソッドは、概念は異なりますが、定義は非常に似ています。関数定義ステートメントにはレシーバーがないため、ステートメントを go ファイル内および go パッケージ内で直接定義できます。

func main() {
    sum := add(1, 2)
    fmt.Println(sum)
}

func add(a, b int) int {
    return a + b
}
ログイン後にコピー

この例では、add を関数として定義しました。その関数シグネチャは func add(a, b int) int であり、直接レシーバーはありません。これは go のパッケージ内で定義されており、直接呼び出すことができます。たとえば、例の main 関数は add 関数を呼び出します。

例の関数名は小文字の add で始まるため、そのスコープは宣言されたパッケージにのみ属し、他のパッケージでは使用できません。大文字の場合、関数のスコープは広く、他のパッケージから呼び出すことができます。これは、Go 言語における大文字と小文字の使用でもあります。たとえば、Java では、スコープを宣言する特別なキーワード privateprotectpublic# があります。 ##など

/*
 提供的常用库,有一些常用的方法,方便使用
*/
package lib

// 一个加法实现
// 返回a+b的值
func Add(a, b int) int {
    return a + b
}
ログイン後にコピー

上の例で定義された

Add メソッドは、他のパッケージから呼び出すことができます。

メソッド

メソッドの宣言は関数の宣言と似ていますが、異なる点は、メソッドを定義するときに、メソッドが

func# の間に配置されることです。 ## とメソッド名。パラメーターを追加します。このパラメーターはレシーバーなので、定義したメソッドはレシーバーにバインドされ、レシーバーのメソッドと呼ばれます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>type person struct { name string } func (p person) String() string{ return &quot;the person name is &quot;+p.name }</pre><div class="contentsignin">ログイン後にコピー</div></div> この例では、

func

とメソッド名の間に追加されたパラメーター (p person) に注目してください。これがレシーバーです。ここで、型 person には String メソッドがあるとします。次に、その使用方法を見てみましょう。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>func main() { p:=person{name:&quot;张三&quot;} fmt.Println(p.String()) }</pre><div class="contentsignin">ログイン後にコピー</div></div>呼び出しメソッドは非常に簡単です。型変数を使用して呼び出すだけです。型変数とメソッドの前に

.

演算子があり、この型変数の特定のメソッドが呼び出されることを示しますという意味です。 Go 言語には、値レシーバーとポインター レシーバーの 2 種類のレシーバーがあります。上の例では、値型レシーバーを使用しています。

値型レシーバーによって定義されたメソッドを使用すると、呼び出されたときに実際に値レシーバーのコピーが使用されるため、値に対する操作は元の型変数に影響を与えません。

func main() {
    p:=person{name:"张三"}
    p.modify() //值接收者,修改无效
    fmt.Println(p.String())
}

type person struct {
    name string
}

func (p person) String() string{
    return "the person name is "+p.name
}

func (p person) modify(){
    p.name = "李四"
}
ログイン後にコピー

上記の例では、出力される値は依然として

张三

であり、これに対する変更は無効です。ポインタをレシーバとして使用すると、ポインタ レシーバはポインタのコピーを元の値に渡すため、機能します。ポインタのコピーは依然として元の型の値を指しているため、それが変更されると、元の型変数の値にも影響します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>func main() { p:=person{name:"张三"} p.modify() //指针接收者,修改有效 fmt.Println(p.String()) } type person struct { name string } func (p person) String() string{ return &quot;the person name is &quot;+p.name } func (p *person) modify(){ p.name = "李四" }</pre><div class="contentsignin">ログイン後にコピー</div></div>これを変更してポインタの受け取り側になるだけで変更は完了です。

メソッドを呼び出す場合、渡されるレシーバーは基本的にコピーですが、1 つは値のコピーで、もう 1 つは値を指すポインターのコピーです。ポインタは元の値を指す性質があるため、ポインタが指す値を変更すると元の値も変更されます。値レシーバーは値のコピーを使用してメソッドを呼び出すのに対し、ポインター レシーバーは実際の値を使用してメソッドを呼び出すことを簡単に理解できます。

上記の例では、ポインター レシーバー メソッドを呼び出すときに、ポインターではなく値変数も使用していることがわかりましたか。次の を使用しても可能です。
p:=person{name:"张三"}
(&p).modify() //指针接收者,修改有效
ログイン後にコピー

これも可能です。呼び出しにポインタの使用を強制しない場合、Go コンパイラは、受信側の要件を満たすポインタを取得するのを自動的に支援します。

同様に、値レシーバーのメソッドである場合は、ポインターを使用して呼び出すこともできます。Go コンパイラーは、レシーバーの要件を満たすために自動的に逆参照します (例: で定義されている

String()例の )

メソッドは次のように呼び出すこともできます: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>p:=person{name:&quot;张三&quot;} fmt.Println((&amp;p).String())</pre><div class="contentsignin">ログイン後にコピー</div></div> つまり、メソッドを呼び出すときは、値またはポインタのいずれかを使用できますが、これらを厳密に遵守する必要はありません。 Go 言語コンパイラが役立ち、自動的にエスケープされるため、開発者は非常に楽になります。

不管是使用值接收者,还是指针接收者,一定要搞清楚类型的本质:对类型进行操作的时候,是要改变当前值,还是要创建一个新值进行返回?这些就可以决定我们是采用值传递,还是指针传递。

Go语言中方法和函数的区别

1、含义不同

函数function是一段具有独立功能的代码,可以被反复多次调用,从而实现代码复用。而方法method是一个类的行为功能,只有该类的对象才能调用。

2、方法有接受者,而函数无接受者

  • Go语言的方法method是一种作用于特定类型变量的函数,这种特定类型变量叫做Receiver(接受者、接收者、接收器);

  • 接受者的概念类似于传统面向对象语言中的this或self关键字;

  • Go语言的接受者强调了方法具有作用对象,而函数没有作用对象;

  • 一个方法就是一个包含了接受者的函数;

  • Go语言中, 接受者的类型可以是任何类型,不仅仅是结构体, 也可以是struct类型外的其他任何类型。

3、函数不可以重名,而方法可以重名

只要接受者不同,则方法名可以一样。

4、调用方式不一样

方法是struct对象通过.点号+名称来调用,而函数是直接使用名称来调用。

方法的调用需要指定类型变量调用,函数则不需要

 ```
var p testMethod.Person
p.Name = "tom"
p.Age = 123
p.ShowInfo()
ログイン後にコピー

注:方法和函数的访问权限都受大小写影响,小写本包,大写全局

5、方法需要指定所属类型,可以是结构体也可以是自定义type,函数则通用

```
func (person Person) ShowInfo(形参) 返回值{

   person.Name = "123"
   person.Age = 12
   fmt.Printf("name=%v,age=%v",person.Name,person.Age)
}
```
 
person为类型的形参,类型为Person
ログイン後にコピー

6、函数的形参与传参类型需要一致,方法可以改变

     ```
func (person *Person) ShowInfo(形参) 返回值{

   person.Name = "123"
   person.Age = 12
   fmt.Printf("name=%v,age=%v",person.Name,person.Age)
}
ログイン後にコピー

(1)这里方法的类型形参为指针,调用时可以使用 p.ShowInfo()或者 (&p).ShowInfo(),本质上都是后者,只不过Go的设计者对于方法的调用做了底层优化

func (person Person) ShowInfo(形参) 返回值{

   person.Name = "123"
   person.Age = 12
   fmt.Printf("name=%v,age=%v",person.Name,person.Age)
}
ログイン後にコピー

(2)这里方法的形参类型为数值型,默认为值传递,而在调用时可以使用p.ShowInfo()或者 (&p).ShowInfo(),但依旧是值拷贝

func test01(i *int) {


}
ログイン後にコピー

(3)对于函数则需保持一致,需要的形参为指针,则传入的形参需为地址值,否则编译无法通过

【相关推荐:Go视频教程编程教学

以上がGo言語のメソッドと関数の違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

Go's Crawler Collyのキュースレッドの問題は何ですか? Go's Crawler Collyのキュースレッドの問題は何ですか? Apr 02, 2025 pm 02:09 PM

Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? GO言語の「VAR」と「タイプ」キーワード定義構造の違いは何ですか? Apr 02, 2025 pm 12:57 PM

GO言語で構造を定義する2つの方法:VARとタイプのキーワードの違い。構造を定義するとき、GO言語はしばしば2つの異なる執筆方法を見ます:最初...

Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Apr 02, 2025 pm 02:03 PM

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか? Apr 02, 2025 pm 05:09 PM

Golandのカスタム構造ラベルが表示されない場合はどうすればよいですか?ゴーランドを使用するためにGolandを使用する場合、多くの開発者はカスタム構造タグに遭遇します...

Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Redisストリームを使用してGO言語でメッセージキューを実装する場合、user_idタイプの変換の問題を解決する方法は? Apr 02, 2025 pm 04:54 PM

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Golang Generic Function Typeの制約がVSCodeで自動的に削除されるという問題を解決する方法は? Apr 02, 2025 pm 02:15 PM

VSCODEユーザーのGolang Generic Function Typeの制約の自動削除は、VSCODEを使用してGolangコードを書くときに奇妙な問題に遭遇する可能性があります。いつ...

See all articles