Подтвердить что ты не робот

В Go, какие значения вид отражают. Поверхность?

j:=1

Kind of j reflect.Int, как и ожидалось.

var j interface{} = 1

Kind of j также reflect.Int.

Какие значения имеют вид reflect.Interface?

4b9b3361

Ответ 1

Если вы ищете практическое решение, ответ прост и раздражает. reflect.TypeOf принимает пустой тип интерфейса, в который вы помещаете все данные, которые хотите передать. Проблема заключается в том, что тип интерфейса не может содержать другой тип интерфейса, а это значит, что вы не можете передать интерфейс reflect.TypeOf. Существует обходной путь, но это немного больно. Что вам нужно сделать, это создать составной тип (например, структуру или фрагмент или карту), где один из типов элементов является типом интерфейса и извлекает его. Например:

var sliceOfEmptyInterface []interface{}
var emptyInterfaceType = reflect.TypeOf(sliceOfEmptyInterface).Elem()

Сначала создается представление reflect.Type []interface{} (фрагмент interface{}), а затем извлекается тип элемента, который равен interface{}.

Предоставлено этот пост.

Ответ 2

Ответы до сих пор кажутся неожиданно запутанными, когда вопрос и его ответ на самом деле прост: отражают. Поверхность - это вид значений интерфейса.

Вы можете легко увидеть, что с помощью

var v interface{}
var t = reflect.ValueOf(&v).Type().Elem()
fmt.Println(t.Kind() == reflect.Interface)

Обратите внимание, что ValueOf(v) не работает, потому что вам нужен тип v, а не его содержимое.

Ответ 3

Хороший вопрос. Я работал над ним почти час, чтобы узнать себя!

Давайте начнем с этого кода:

package main

import (
        "fmt"
        "reflect"
)

// define an interface
type Doer interface {
        Do()
}

// define a type that implements the interface
type T struct{}

func (T) Do() {}

func main() {
        var v Doer = T{}
        fmt.Println(reflect.TypeOf(v).Kind())
}

Выходной сигнал struct, а не interface. (Вы можете запустить его здесь.)

Это потому, что, хотя мы определяем v как переменную , фактическое значение, эта переменная имеет тип T. Его называют "динамическим типом" переменной. Одним из основных пунктов пакета reflect является определение динамического типа интерфейсных переменных, поэтому он дает вам динамический тип, а не интерфейс. (И даже если бы это было необходимо, пакет reflect не смог получить интерфейс переменных, переданных в TypeOf и ValueOf, поскольку переменные передаются как значения для функций.)

Итак, вы можете видеть, что ваш вопрос "какие значения имеют вид interface?", на технически можно ответить "no value".

Но что это за interface хорошо, тогда? Смотрите этот код:

// assuming the above code, just with this main function
func main() {
        a := make([]Doer, 0)
        fmt.Println(reflect.TypeOf(a).Elem().Kind())
}

Отпечатает interface. (Это здесь.) Точка находится в функции Elem, которая возвращает тип элементов карт, тип интерфейса здесь. Elem также работает с указателями, массивами, срезами и каналами. Аналогичная функция для получения типа ключа карты (Key), полей структур (Field и друзей) и аргументов функций и возвращаемого параметра (In и Out). Вы можете рассчитывать на получение типов типа интерфейса из всех этих.

Роб Пайк написал потрясающую статью, The Laws of Reflection, которая очень хорошо объясняет интерфейсы и отражение.

Ответ 4

Я думаю, что ваш вопрос эквивалентен: может ли интерфейс содержать другой интерфейс?

В Законы отражения мы находим это

Переменная интерфейса может хранить любое конкретное (неинтерфейсное) значение

Или более подробно

Переменная типа интерфейса хранит пару: конкретное значение назначенный переменной, и этот дескриптор типа значения. Чтобы быть более точное, значение является базовым конкретным элементом данных, который реализует интерфейс, и тип описывает полный тип этого пункт.

Таким образом, интерфейс не может содержать другой интерфейс. Это означает, что нет значения, значение которого reflect.Kind равно reflect.Interface. Я думаю, вы могли бы создать один с небезопасным, но я не думаю, что вы когда-нибудь увидите его нормально.

Ответ 5

Это зависит от того, что вы подразумеваете под "значением" и "значением типа".

В Go "тип" может означать разные вещи:  - Статический тип (тип времени компиляции) выражения. Каждое выражение на языке имеет статический тип, известный во время компиляции.  - Динамический тип (тип времени выполнения) значения интерфейса. Переменная или выражение типа интерфейса особенность в том, что она может содержать значения разных типов, а тип этого базового значения неизвестен во время компиляции. Это значение времени выполнения и его тип можно проверить во время выполнения.

Отражение происходит во время выполнения, поэтому интересно только задать динамический тип значения интерфейса. Таким образом, вы должны говорить о типе базового значения значения интерфейса.

Значение интерфейса не nil в основном представляет собой "обертку" вокруг базового значения и типа. Обратите внимание, что этот базовый тип не может быть типом интерфейса. т.е. оболочка не может "обернуть" другую оболочку. Это то, что говорит joshlf13. Это связано с тем, что при назначении из одного типа интерфейса другому типу интерфейса передается только базовое значение. Тип интерфейса, из которого он пришел, не запоминается. Таким образом, невозможно создать значение интерфейса, базовым типом которого является тип интерфейса.

Функции отражения, такие как reflect.ValueOf() и reflect.TypeOf(), позволяют передать значение интерфейса и получить представление базового значения. Тип параметра interface{}, потому что это тот тип, который позволяет вам передать что угодно. Однако они предполагают, что вы действительно интересны в базовом значении этого значения интерфейса, которое вы либо превратили в interface{}, передав его в первую очередь, либо вы получили его из другого места и хотите его изучить. Таким образом, функции отражения фундаментальны для изучения базового значения интерфейсов (которые, как объяснялось выше, должны иметь тип неинтерфейса), а не фактический аргумент типа интерфейса.

Поэтому, если ваш вопрос: что v может сделать reflect.ValueOf(v).Kind() для оценки Interface; ответ - ничто. Это связано с тем, что если v не nil, то ValueOf() получает представление своего базового значения, которое должно быть типа без интерфейса. И если v есть nil, то по документации reflect.ValueOf() он возвращает нулевое значение типа Value, а документация для типа Value.Kind() говорит, что вызов Kind() по нулевому значению возвращает Invalid.

Ответ 6

Вы не можете получить непосредственно тип значения interface{}, но вы можете пройти через указатель указателя:

reflect.TypeOf(new(interface{})).Elem()

Запустите этот на play.golang.org:

t := reflect.TypeOf(new(interface{})).Elem()
fmt.Printf("Type: %s\n", t)
fmt.Printf("Kind: %v\n", t.Kind())
fmt.Printf("IsInterface: %v\n", t.Kind() == reflect.Interface)

Вывод:

Type: interface {}
Kind: interface
IsInterface: true

Ответ 7

Я сделаю для этого ясный ответ.

сначала вам нужно, чтобы теперь все интерфейсы могли удерживать что угодно, кроме другого интерфейса. так что сделайте это ясно. взгляните на эту программу.

type i interface {
  hello()
 }
 type s struct{
 name string
 }
 func (a s)hello(){} 
 func main(){
  var f i //here we create an empty interface i
  f=s{} //now f hold a structure of type s
  fmt.Print(reflect.ValueOf(f).Kind())   // here we got a structure type so what really happen now i will explained  
  }

подпись метода ValueOf:

 reflect.ValueOf(i interface{}) 

поэтому ValueOf всегда получает интерфейс ampty, что я сказал вам, что интерфейс никогда не поддерживает другой интерфейс. valueOf не будет принимать f-интерфейс, но wlli возьмет пустой интерфейс, содержащий структуру s. это похоже на то, что мы ввели базовое значение f и назначили пустой интерфейс и передали методу ValueOf