Sintaks deklarasi fungsi: hal-hal dalam tanda kurung sebelum nama fungsi

250

Maaf saya tidak bisa lebih spesifik dalam judul pertanyaan, tetapi saya membaca beberapa kode Go dan saya menemukan deklarasi fungsi dari formulir ini:

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    ...
}

dari https://github.com/mattermost/platform/blob/master/api/context.go

func (s *GracefulServer) BlockingClose() bool {
    ...
}

dari https://github.com/braintree/manners/blob/master/server.go

Apa arti dari (h handler)dan (s *GracefulServer)antara kurung? Apa arti seluruh pernyataan fungsi, dengan mempertimbangkan arti hal-hal antara tanda kurung?

Edit

Ini bukan duplikat Whats perbedaan fungsi dan metode di Go? : pertanyaan ini datang kepada saya karena saya tidak tahu apa hal-hal dalam tanda kurung sebelum nama fungsi, bukan karena saya bertanya-tanya apa perbedaan antara fungsi dan metode ... jika saya tahu bahwa deklarasi ini adalah metode saya tidak akan ' Saya tidak memiliki pertanyaan ini sejak awal. Jika seseorang memiliki keraguan yang sama dengan saya suatu hari, saya tidak percaya dia akan pergi mencari "metode golang" karena dia tidak tahu bahwa ini masalahnya. Ini akan seperti bertanya-tanya apa arti huruf "sigma" sebelum ekspresi matematika (tidak tahu itu berarti penjumlahan) dan seseorang mengatakan itu duplikat dari apa perbedaan antara penjumlahan dan beberapa hal lainnya.

Juga, jawaban singkat untuk pertanyaan ini ("itu penerima") bukanlah jawaban untuk "apa perbedaan antara fungsi dan metode".

Marcus Vinícius Monteiro
sumber
27
@ Volker kemudian meletakkan penafian yang mengatakan bahwa orang-orang Go di stackoverflow hanya menjawab pertanyaan yang tidak ada di Tour of Go. Di komunitas Haskell, orang dapat mengajukan pertanyaan seperti Bagaimana saya bisa mendapatkan nelemen th dari daftar di Haskell? , yang ada di Pendahuluan tentang Pelajari Anda Haskell untuk Great Good dan jawab pertanyaan mereka tanpa keributan.
Marcus Vinícius Monteiro
23
Ketika saya memiliki pertanyaan ini, saya pertama kali pergi ke Go Tour. Saya memeriksa semua judul "Fungsi" dan tidak ada contoh yang membahas hal ini. tour.golang.org/basics/4 tour.golang.org/basics/5 Jika Anda tidak tahu untuk memperluas Metode dan antarmuka, Anda tidak akan melihat judul "Metode adalah fungsi". Pertanyaan ini valid dan bagus untuk pengindeksan Google. Penggila bendera duplikat perlu meringankan.
Bruno Bronosky
14
Terima kasih karena tidak spesifik dalam pertanyaan Anda, karena itu cukup membantu saya menemukan jawabannya!
David K
1
Anda bertanya persis apa yang saya cari, itu pertanyaan yang valid. Terima kasih. Saya membaca semua jenis definisi fungsi dan tidak ada yang menjelaskan hal ini. Saya masih mencoba menulis pertanyaan nube saya dan menemukan ini.
Ajak6

Jawaban:

200

Ini disebut 'penerima'. Dalam kasus pertama (h handler)itu adalah tipe nilai, yang kedua (s *GracefulServer)adalah pointer. Cara ini bekerja di Go mungkin sedikit berbeda dari beberapa bahasa lain. Namun tipe penerima, bekerja kurang lebih seperti kelas di sebagian besar pemrograman berorientasi objek. Ini adalah hal yang Anda panggil dari metode, seperti jika saya meletakkan beberapa metode Adi samping beberapa kelas Personmaka saya akan membutuhkan turunan tipe Personuntuk memanggil A(anggap itu metode turunan dan bukan statis!).

Salah satu yang perlu di sini adalah bahwa penerima akan didorong ke tumpukan panggilan seperti argumen lain jadi jika penerima adalah tipe nilai, seperti dalam kasus handlermaka Anda akan bekerja pada salinan dari hal yang Anda panggil metode yang berarti sesuatu seperti h.Name = "Evan"akan tidak bertahan setelah Anda kembali ke lingkup panggilan. Untuk alasan ini apa pun yang mengharapkan untuk mengubah keadaan penerima, perlu menggunakan pointer atau mengembalikan nilai yang dimodifikasi (memberikan lebih banyak paradigma tipe tidak berubah jika Anda mencari itu).

Inilah bagian yang relevan dari spec; https://golang.org/ref/spec#Method_sets

evanmcdonnal
sumber
6
Penjelasan yang bagus dan poin karma tambahan untuk menghubungkan ke spec yang relevan
Marius Waldal
4
Tur golang memiliki beberapa contoh yang sangat berguna juga tour.golang.org/methods/1
tw_hoff
90

Artinya ServeHTTPbukan fungsi yang berdiri sendiri. Tanda kurung sebelum nama fungsi adalah cara Go untuk mendefinisikan objek tempat fungsi-fungsi ini akan beroperasi. Jadi, pada dasarnya ServeHTTPadalah metode type handler dan dapat dipanggil menggunakan objek apa pun, misalnya h, dari tipe handler.

h.ServeHTTP(w, r)

Mereka juga disebut penerima. Ada dua cara untuk mendefinisikannya. Jika Anda ingin memodifikasi penerima, gunakan pointer seperti:

func (s *MyStruct) pointerMethod() { } // method on pointer

Jika Anda tidak perlu memodifikasi penerima, Anda dapat mendefinisikan penerima sebagai nilai seperti:

func (s MyStruct)  valueMethod()   { } // method on value

Contoh ini dari taman bermain Go menunjukkan konsep.

package main

import "fmt"

type Mutatable struct {
    a int
    b int
}

func (m Mutatable) StayTheSame() {
    m.a = 5
    m.b = 7
}

func (m *Mutatable) Mutate() {
    m.a = 5
    m.b = 7
}

func main() {
    m := &Mutatable{0, 0}
    fmt.Println(m)
    m.StayTheSame()
    fmt.Println(m)
    m.Mutate()
    fmt.Println(m)

Output dari program di atas adalah:

&{0 0}
&{0 0}
&{5 7}
Abhishek Nalin
sumber