[Golang] перепутал интерфейс указателя Nil и интерфейс Nil - PullRequest
0 голосов
/ 18 марта 2020

Недавно я читаю книгу "Язык программирования Go". В главе 7.5 я запутался в приведенном ниже коде. Почему f (buf) будет pani c, а f (w)?

package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
)

func main() {
    var w io.Writer
    fmt.Printf("%T\n", w)

    f(w)

    w = os.Stdout
    fmt.Printf("%T\n", w)

    w = new(bytes.Buffer)
    fmt.Printf("%T\n", w)

    var buf *bytes.Buffer
    fmt.Printf("%T\n", buf)
    f(buf)
}

func f(out io.Writer)  {

    fmt.Printf("%T\n", out)
    if out != nil {
        out.Write([]byte("done!\n"))
    }
}

1 Ответ

1 голос
/ 18 марта 2020

Тип интерфейса в Go - это пара, содержащая базовый тип и значение. Когда вы создаете переменную интерфейса:

var w io.Writer

, она инициализируется нулевым значением, которое для интерфейсов равно nil. Когда вы передаете это функции, которая ожидает io.Writer, она передается как nil.

Инициализация аналогична переменной указателя неинтерфейса:

var buf *bytes.Buffer

Здесь buf равно nil. Однако, когда вы передаете buf функции, которая принимает io.Writer, она должна быть передана как интерфейс. Go преобразует значение buf в интерфейс, тип которого равен *bytes.Buffer, а базовое значение - nil. Однако сам этот интерфейс не nil.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...