Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah antara muka `penyapa` Go tidak boleh diberikan nilai `tourGuide`, tetapi boleh diberikan penuding kepada `tourGuide`?

Mengapakah antara muka `penyapa` Go tidak boleh diberikan nilai `tourGuide`, tetapi boleh diberikan penuding kepada `tourGuide`?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-20 01:38:03169semak imbas

Why can't a Go `greeter` interface be assigned a `tourGuide` value, but can be assigned a pointer to a `tourGuide`?

Jenis Kaedah Go Struct Yang Memuaskan Antara Muka

Memandangkan contoh kod Go berikut:

package main

import "fmt"

type greeter interface {
    hello()
    goodbye()
}

type tourGuide struct {
    name string
}

func (t tourGuide) hello() {
    fmt.Println("Hello", t.name)
}

func (t *tourGuide) goodbye() {
    fmt.Println("Goodbye", t.name)
}

func main() {
    var t1 tourGuide = tourGuide{"James"}
    t1.hello()   // Hello James
    t1.goodbye() // Goodbye James (same as (&t1).goodbye())

    var t2 *tourGuide = &tourGuide{"Smith"}
    t2.hello()   // Hello Smith
    t2.goodbye() // Goodbye Smith (same as (*t2).hello())

    // illegal: t1 is not assignable to g1 (why?)
    // var g1 greeter = t1

    var g2 greeter = t2
    g2.hello()   // Hello Smith
    g2.goodbye() // Goodbye Smith
}

Dalam kod di atas, anda boleh panggil dua kaedah struct tourGuide menggunakan sama ada pembolehubah jenis tourGuide (t1) atau penunjuk ke tourGuide (t2). Walau bagaimanapun, apabila melaksanakan antara muka, perkara berubah. Pembolehubah jenis antara muka penyambut boleh diberikan daripada penuding kepada tourGuide, tetapi bukan daripada nilai tourGuide. Mengapakah ini berlaku?

Jenis Penerima dan Semantik Nilai

Untuk memahami sebabnya, adalah penting untuk memahami konsep jenis penerima dan semantik nilai. Kaedah dalam Go boleh mempunyai sama ada penerima nilai atau penerima penunjuk. Kaedah penerima nilai digunakan pada salinan nilai, manakala kaedah penerima penunjuk digunakan pada nilai asal.

Apabila nilai disalin, ia mencipta salinan bebas baharu bagi nilai asal. Sebarang pengubahsuaian yang dibuat pada salinan tidak menjejaskan nilai asal. Ini dikenali sebagai semantik nilai.

Dalam contoh TourGuide, kaedah hello mempunyai penerima nilai, dan kaedah selamat tinggal mempunyai penerima penunjuk. Apabila anda memanggil t1.hello(), salinan t1 dibuat dan kaedah hello digunakan pada salinan. Apabila anda memanggil t1.goodbye(), kaedah selamat tinggal digunakan pada nilai t1 asal.

Antara Muka dan Semantik Nilai

Antaramuka dalam Go dilaksanakan oleh semantik nilai. Ini bermakna apabila nilai diberikan kepada antara muka, salinan nilai dibuat. Dalam kes kaedah penerima penunjuk, ini bermakna salinan nilai tidak mempunyai alamat, dan oleh itu kaedah tidak boleh digunakan padanya.

Sebagai contoh, apabila anda menetapkan t1 kepada g1 (yang ialah nilai antara muka) dalam baris kod berikut:

// illegal: t1 is not assignable to g1 (why?)
// var g1 greeter = t1

salinan t1 dibuat, dan kaedah hello dan goodbye dilaksanakan pada salinan. Walau bagaimanapun, kerana salinan tidak mempunyai alamat, kaedah selamat tinggal tidak boleh digunakan padanya.

Sebaliknya, apabila anda menetapkan t2 kepada g2 dalam baris kod berikut:

var g2 greeter = t2

salinan t2 (yang merupakan penunjuk kepada tourGuide) dicipta, dan kaedah hello dan goodbye dilaksanakan pada salinan penunjuk. Dalam kes ini, salinan penuding mempunyai alamat, jadi kaedah selamat tinggal boleh digunakan padanya.

Kesimpulan

Ringkasnya, sebab pembolehubah antara muka penyambut jenis boleh diserahkan daripada penunjuk ke tourGuide tetapi bukan dari nilai tourGuide adalah kerana antara muka dilaksanakan oleh semantik nilai. Apabila nilai diberikan kepada antara muka, salinan nilai dibuat dan jika kaedah antara muka mempunyai penerima penunjuk, ia tidak boleh digunakan pada salinan kerana salinan itu tidak mempunyai alamat.

Atas ialah kandungan terperinci Mengapakah antara muka `penyapa` Go tidak boleh diberikan nilai `tourGuide`, tetapi boleh diberikan penuding kepada `tourGuide`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn