Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как использовать утверждение типа из отражения интерфейса в golang?

Автор вопроса: Night OwlОтветов: 1

Я пытаюсь использовать утверждение типа в golang. с прямым утверждением проблем нет.

a, ok := i.(MyStruct)

но когда я использую отражение

b, ok := i.(reflect.TypeOf(i))

У меня ошибка. Что было проблемой с этим? и как с этим бороться?

Полный код:

package main

import (
     "fmt"
     "reflect"
)

type MyStruct struct {
    field string
}

func main() {
    var i interface{} = MyStruct{field:"Thanks"}

    a, ok := i.(MyStruct)
    fmt.Println(a, ok)

    t := reflect.TypeOf(i)
    fmt.Println(t)

    b, ok := i.(t)
    fmt.Println(b, ok)
}

Спасибо за ваши ответы.

  • Возможный дубликат 1, 2 I Love Reflection 30.01.2020

gotypesinterfaceassertionreflect

Ответы

Ответ 1 · рейтинг 4 · hobbs

Много чего, но в основном "это так не работает". То, что находится внутри скобок в утверждении типа, должно быть типом, то есть именем типа или литерал типа. reflect.TypeOf(i) не является одним из них, это выражение вызова метода. Следовательно, это синтаксическая ошибка. reflect.TypeOf не "возвращает тип" (что на самом деле не имеет значения вы можете сделать в Go), он возвращает reflect.Type, который является обычным go структура, содержащая информацию о типе (т. е. вид метатипа).

Но более фундаментальная причина, по которой он не работает, заключается в том, что он не может... Go должен знать тип переменной при ее объявлении. Либо его тип задается явно в объявлении var, либо он выводится из типа значения инициализации в объявлении var x = value или коротком присваивании x := value. Невозможно, чтобы тип был неизвестен во время компиляции. Go не позволяет вам написать выражение, которое дает неопределенный тип.

Сама цель утверждения типа состоит в том, чтобы получить значение типа интерфейса (который является своего рода "коробкой", которая может содержать значения нескольких типов или, для interface{}, вообще любого типа) и получить значение конкретный конкретный тип. Значение, созданное утверждением, будет иметь тип, названный утверждением, и никакой другой. (В случае назначения ,ok, если утверждение не выполняется, переменная будет содержать нулевое значение но при этом иметь правильный тип). Если бы вы могли написать утверждение для типа, который был известен только во время выполнения, все развалилось бы, поэтому вы не можете его написать - это ошибка.

Короче говоря, вы не можете использовать отражение для этого. Вы можете использовать Reflect, чтобы узнать, что такое тип i, вы можете узнать имя этого типа, вы можете узнать, что лежит в основе Kind - это Struct, вы можете перечислить поля структуры и получить из них значения и т. д... все это законное использование отражения. Но он не может вернуть вам переменную типа MyStruct - это можно сделать с помощью i.(MyStruct).

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы