Почему преобразование типов не выполняется во время компиляции? - PullRequest
0 голосов
/ 01 ноября 2019

Рассмотрим следующий фрагмент кода:

package main

import "fmt"

type Interface interface {
    Fun()
}

type Int int

func (Int) Fun() {}

func main() {
    var x interface{}
    x = Int(42)
    if _, ok := x.(int); !ok {
        fmt.Println("type assertion fails")
    }

    // why do the lines below fail to compile?  
    var y Interface
    y = Int(42)
    if _, ok := y.(int); !ok {
        fmt.Println("type assertion fails")
    }
}

Утверждение первого типа выполняется должным образом. Однако во втором случае утверждение типа выполняется во время компиляции (другими словами, программа не компилируется)

утверждение невозможного типа: int не реализует интерфейс (отсутствует метод Fun)

Из прочтения «Язык программирования Go» (стр. 206) я понимаю, что второй фрагмент кода должен скомпилироваться, а преобразование типа должно произойти сбой во время выполнения.

Есть ли разница между этими 2 фрагментами;не являются ли x и y типа интерфейса (разные интерфейсы)? И почему секунда терпит неудачу во время компиляции?

Исходя из фона C ++, это очень похоже на объединение static_assert (время компиляции) и assert (время выполнения) в одно утверждение типа,что выглядит немного странно.

1 Ответ

1 голос
/ 01 ноября 2019

Из спецификации:

Точнее, если T не является типом интерфейса, x. (T) утверждает, что динамический тип x идентичен типу T. В этом случаеT должен реализовывать тип (interface) x;в противном случае утверждение типа недопустимо, поскольку для x невозможно сохранить значение типа T. Если T является типом интерфейса, x. (T) утверждает, что динамический тип x реализует интерфейс T.

https://golang.org/ref/spec#Type_assertions

Таким образом, ожидается, что он не скомпилируется, поскольку int не является типом интерфейса;и он не реализует x (Interface).

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